Coverage for pyTooling / CLIAbstraction / Argument.py: 89%
226 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-28 12:48 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-28 12:48 +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).
36"""
37from abc import abstractmethod
38from pathlib import Path
39from typing import ClassVar, List, Union, Iterable, TypeVar, Generic, Any, Optional as Nullable, Self
41try:
42 from pyTooling.Decorators import export, readonly
43 from pyTooling.Common import getFullyQualifiedName
44except (ImportError, ModuleNotFoundError): # pragma: no cover
45 print("[pyTooling.Versioning] Could not import from 'pyTooling.*'!")
47 try:
48 from Decorators import export, readonly
49 from Common import getFullyQualifiedName
50 except (ImportError, ModuleNotFoundError) as ex: # pragma: no cover
51 print("[pyTooling.Versioning] Could not import directly!")
52 raise ex
55__all__ = ["ValueT"]
58ValueT = TypeVar("ValueT") #: The type of value in a valued argument.
61@export
62class CommandLineArgument:
63 """
64 Base-class for all *Argument* classes.
66 An argument instance can be converted via ``AsArgument`` to a single string value or a sequence of string values
67 (tuple) usable e.g. with :class:`subprocess.Popen`. Each argument class implements at least one ``pattern`` parameter
68 to specify how argument are formatted.
70 There are multiple derived formats supporting:
72 * commands |br|
73 |rarr| :mod:`~pyTooling.CLIAbstraction.Command`
74 * simple names (flags) |br|
75 |rarr| :mod:`~pyTooling.CLIAbstraction.Flag`, :mod:`~pyTooling.CLIAbstraction.BooleanFlag`
76 * simple values (vlaued flags) |br|
77 |rarr| :class:`~pyTooling.CLIAbstraction.Argument.StringArgument`, :class:`~pyTooling.CLIAbstraction.Argument.PathArgument`
78 * names and values |br|
79 |rarr| :mod:`~pyTooling.CLIAbstraction.ValuedFlag`, :mod:`~pyTooling.CLIAbstraction.OptionalValuedFlag`
80 * key-value pairs |br|
81 |rarr| :mod:`~pyTooling.CLIAbstraction.NamedKeyValuePair`
82 """
84 _pattern: ClassVar[str]
86 def __init_subclass__(cls, *args: Any, pattern: Nullable[str] = None, **kwargs: Any) -> None:
87 """
88 This method is called when a class is derived.
90 :param args: Any positional arguments.
91 :param pattern: This pattern is used to format an argument. |br|
92 Default: ``None``.
93 :param kwargs: Any keyword argument.
94 """
95 super().__init_subclass__(*args, **kwargs)
96 cls._pattern = pattern
98 # TODO: the whole class should be marked as abstract
99 # TODO: a decorator should solve the issue and overwrite the __new__ method with that code
100 def __new__(cls, *args: Any, **kwargs: Any) -> Self:
101 """
102 Check if this class was directly instantiated without being derived to a subclass. If so, raise an error.
104 :param args: Any positional arguments.
105 :param kwargs: Any keyword arguments.
106 :raises TypeError: When this class gets directly instantiated without being derived to a subclass.
107 """
108 if cls is CommandLineArgument:
109 raise TypeError(f"Class '{cls.__name__}' is abstract.")
111 # TODO: not sure why parameters meant for __init__ do reach this level and distract __new__ from it's work
112 return super().__new__(cls)
114 # TODO: Add property to read pattern
116 @abstractmethod
117 def AsArgument(self) -> Union[str, Iterable[str]]: # type: ignore[empty-body]
118 """
119 Convert this argument instance to a string representation with proper escaping using the matching pattern based on
120 the internal name and value.
122 :return: Formatted argument.
123 :raises NotImplementedError: This is an abstract method and must be overwritten by a subclass.
124 """
125 raise NotImplementedError(f"Method 'AsArgument' is an abstract method and must be implemented by a subclass.")
127 @abstractmethod
128 def __str__(self) -> str: # type: ignore[empty-body]
129 """
130 Return a string representation of this argument instance.
132 :return: Argument formatted and enclosed in double quotes.
133 :raises NotImplementedError: This is an abstract method and must be overwritten by a subclass.
134 """
135 raise NotImplementedError(f"Method '__str__' is an abstract method and must be implemented by a subclass.")
137 @abstractmethod
138 def __repr__(self) -> str: # type: ignore[empty-body]
139 """
140 Return a string representation of this argument instance.
142 .. note:: By default, this method is identical to :meth:`__str__`.
144 :return: Argument formatted and enclosed in double quotes.
145 :raises NotImplementedError: This is an abstract method and must be overwritten by a subclass.
146 """
147 raise NotImplementedError(f"Method '__repr__' is an abstract method and must be implemented by a subclass.")
150@export
151class ExecutableArgument(CommandLineArgument):
152 """
153 Represents the executable.
154 """
156 _executable: Path
158 def __init__(self, executable: Path) -> None:
159 """
160 Initializes a ExecutableArgument instance.
162 :param executable: Path to the executable.
163 :raises TypeError: If parameter 'executable' is not of type :class:`~pathlib.Path`.
164 """
165 if not isinstance(executable, Path):
166 ex = TypeError("Parameter 'executable' is not of type 'Path'.")
167 ex.add_note(f"Got type '{getFullyQualifiedName(executable)}'.")
168 raise ex
170 self._executable = executable
172 @property
173 def Executable(self) -> Path:
174 """
175 Get the internal path to the wrapped executable.
177 :return: Internal path to the executable.
178 """
179 return self._executable
181 @Executable.setter
182 def Executable(self, value: Path) -> None:
183 """
184 Set the internal path to the wrapped executable.
186 :param value: Value to path to the executable.
187 :raises TypeError: If value is not of type :class:`~pathlib.Path`.
188 """
189 if not isinstance(value, Path):
190 ex = TypeError("Parameter 'value' is not of type 'Path'.")
191 ex.add_note(f"Got type '{getFullyQualifiedName(value)}'.")
192 raise ex
194 self._executable = value
196 def AsArgument(self) -> Union[str, Iterable[str]]:
197 """
198 Convert this argument instance to a string representation with proper escaping using the matching pattern based on
199 the internal path to the wrapped executable.
201 :return: Formatted argument.
202 """
203 return f"{self._executable}"
205 def __str__(self) -> str:
206 """
207 Return a string representation of this argument instance.
209 :return: Argument formatted and enclosed in double quotes.
210 """
211 return f"\"{self._executable}\""
213 __repr__ = __str__
216@export
217class DelimiterArgument(CommandLineArgument, pattern="--"):
218 """
219 Represents a delimiter symbol like ``--``.
220 """
222 def __init_subclass__(cls, *args: Any, pattern: str = "--", **kwargs: Any) -> None:
223 """
224 This method is called when a class is derived.
226 :param args: Any positional arguments.
227 :param pattern: This pattern is used to format an argument. |br|
228 Default: ``"--"``.
229 :param kwargs: Any keyword argument.
230 """
231 kwargs["pattern"] = pattern
232 super().__init_subclass__(*args, **kwargs)
234 def AsArgument(self) -> Union[str, Iterable[str]]:
235 """
236 Convert this argument instance to a string representation with proper escaping using the matching pattern.
238 :return: Formatted argument.
239 """
240 return self._pattern
242 def __str__(self) -> str:
243 """
244 Return a string representation of this argument instance.
246 :return: Argument formatted and enclosed in double quotes.
247 """
248 return f"\"{self._pattern}\""
250 __repr__ = __str__
253@export
254class NamedArgument(CommandLineArgument, pattern="{0}"):
255 """
256 Base-class for all command line arguments with a name.
257 """
259 _name: ClassVar[str]
261 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "{0}", **kwargs: Any) -> None:
262 """
263 This method is called when a class is derived.
265 :param args: Any positional arguments.
266 :param name: Name of the CLI argument.
267 :param pattern: This pattern is used to format an argument. |br|
268 Default: ``"{0}"``.
269 :param kwargs: Any keyword argument.
270 """
271 kwargs["pattern"] = pattern
272 super().__init_subclass__(*args, **kwargs)
273 cls._name = name
275 # TODO: the whole class should be marked as abstract
276 # TODO: a decorator should solve the issue and overwrite the __new__ method with that code
277 def __new__(cls, *args: Any, **kwargs: Any) -> Self:
278 """
279 Check if this class was directly instantiated without being derived to a subclass. If so, raise an error.
281 :param args: Any positional arguments.
282 :param kwargs: Any keyword arguments.
283 :raises TypeError: When this class gets directly instantiated without being derived to a subclass.
284 """
285 if cls is NamedArgument:
286 raise TypeError(f"Class '{cls.__name__}' is abstract.")
287 return super().__new__(cls, *args, **kwargs)
289 @readonly
290 def Name(self) -> str:
291 """
292 Get the internal name.
294 :return: Internal name.
295 """
296 return self._name
298 def AsArgument(self) -> Union[str, Iterable[str]]:
299 """
300 Convert this argument instance to a string representation with proper escaping using the matching pattern based on
301 the internal name.
303 :return: Formatted argument.
304 :raises ValueError: If internal name is None.
305 """
306 if self._name is None: 306 ↛ 307line 306 didn't jump to line 307 because the condition on line 306 was never true
307 raise ValueError(f"Internal value '_name' is None.")
309 return self._pattern.format(self._name)
311 def __str__(self) -> str:
312 """
313 Return a string representation of this argument instance.
315 :return: Argument formatted and enclosed in double quotes.
316 """
317 return f"\"{self.AsArgument()}\""
319 __repr__ = __str__
322@export
323class ValuedArgument(CommandLineArgument, Generic[ValueT], pattern="{0}"):
324 """
325 Base-class for all command line arguments with a value.
326 """
328 _value: ValueT
330 def __init_subclass__(cls, *args: Any, pattern: str = "{0}", **kwargs: Any) -> None:
331 """
332 This method is called when a class is derived.
334 :param args: Any positional arguments.
335 :param pattern: This pattern is used to format an argument. |br|
336 Default: ``"{0}"``.
337 :param kwargs: Any keyword argument.
338 """
339 kwargs["pattern"] = pattern
340 super().__init_subclass__(*args, **kwargs)
342 def __init__(self, value: ValueT) -> None:
343 """
344 Initializes a ValuedArgument instance.
346 :param value: Value to be stored internally.
347 :raises TypeError: If parameter 'value' is None.
348 """
349 if value is None: 349 ↛ 350line 349 didn't jump to line 350 because the condition on line 349 was never true
350 raise ValueError("Parameter 'value' is None.")
352 self._value = value
354 @property
355 def Value(self) -> ValueT:
356 """
357 Get the internal value.
359 :return: Internal value.
360 """
361 return self._value
363 @Value.setter
364 def Value(self, value: ValueT) -> None:
365 """
366 Set the internal value.
368 :param value: Value to set.
369 :raises ValueError: If value to set is None.
370 """
371 if value is None: 371 ↛ 372line 371 didn't jump to line 372 because the condition on line 371 was never true
372 raise ValueError(f"Value to set is None.")
374 self._value = value
376 def AsArgument(self) -> Union[str, Iterable[str]]:
377 """
378 Convert this argument instance to a string representation with proper escaping using the matching pattern based on
379 the internal value.
381 :return: Formatted argument.
382 """
383 return self._pattern.format(self._value)
385 def __str__(self) -> str:
386 """
387 Return a string representation of this argument instance.
389 :return: Argument formatted and enclosed in double quotes.
390 """
391 return f"\"{self.AsArgument()}\""
393 __repr__ = __str__
396class NamedAndValuedArgument(NamedArgument, ValuedArgument, Generic[ValueT], pattern="{0}={1}"):
397 """
398 Base-class for all command line arguments with a name and a value.
399 """
401 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "{0}={1}", **kwargs: Any) -> None:
402 """
403 This method is called when a class is derived.
405 :param args: Any positional arguments.
406 :param name: Name of the CLI argument.
407 :param pattern: This pattern is used to format an argument. |br|
408 Default: ``"{0}={1}"``.
409 :param kwargs: Any keyword argument.
410 """
411 kwargs["name"] = name
412 kwargs["pattern"] = pattern
413 super().__init_subclass__(*args, **kwargs)
414 del kwargs["name"]
415 del kwargs["pattern"]
416 ValuedArgument.__init_subclass__(*args, **kwargs)
418 def __init__(self, value: ValueT) -> None:
419 ValuedArgument.__init__(self, value)
421 def AsArgument(self) -> Union[str, Iterable[str]]:
422 """
423 Convert this argument instance to a string representation with proper escaping using the matching pattern based on
424 the internal name and value.
426 :return: Formatted argument.
427 :raises ValueError: If internal name is None.
428 """
429 if self._name is None: 429 ↛ 430line 429 didn't jump to line 430 because the condition on line 429 was never true
430 raise ValueError(f"Internal value '_name' is None.")
432 return self._pattern.format(self._name, self._value)
434 def __str__(self) -> str:
435 """
436 Return a string representation of this argument instance.
438 :return: Argument formatted and enclosed in double quotes.
439 """
440 return f"\"{self.AsArgument()}\""
442 __repr__ = __str__
445class NamedTupledArgument(NamedArgument, ValuedArgument, Generic[ValueT], pattern="{0}"):
446 """
447 Class and base-class for all TupleFlag classes, which represents an argument with separate value.
449 A tuple argument is a command line argument followed by a separate value. Name and value are passed as two arguments
450 to the executable.
452 **Example: **
454 * `width 100``
455 """
457 _valuePattern: ClassVar[str]
459 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "{0}", valuePattern: str = "{0}", **kwargs: Any) -> None:
460 """
461 This method is called when a class is derived.
463 :param args: Any positional arguments.
464 :param name: Name of the CLI argument.
465 :param pattern: This pattern is used to format the CLI argument name. |br|
466 Default: ``"{0}"``.
467 :param valuePattern: This pattern is used to format the value. |br|
468 Default: ``"{0}"``.
469 :param kwargs: Any keyword argument.
470 """
471 kwargs["name"] = name
472 kwargs["pattern"] = pattern
473 super().__init_subclass__(*args, **kwargs)
474 cls._valuePattern = valuePattern
476 # TODO: the whole class should be marked as abstract
477 # TODO: a decorator should solve the issue and overwrite the __new__ method with that code
478 def __new__(cls, *args: Any, **kwargs: Any) -> Self:
479 """
480 Check if this class was directly instantiated without being derived to a subclass. If so, raise an error.
482 :param args: Any positional arguments.
483 :param kwargs: Any keyword arguments.
484 :raises TypeError: When this class gets directly instantiated without being derived to a subclass.
485 """
486 if cls is NamedTupledArgument:
487 raise TypeError(f"Class '{cls.__name__}' is abstract.")
488 return super().__new__(cls, *args, **kwargs)
490 def __init__(self, value: ValueT) -> None:
491 ValuedArgument.__init__(self, value)
493 # TODO: Add property to read value pattern
495 # @property
496 # def ValuePattern(self) -> str:
497 # if self._valuePattern is None:
498 # raise ValueError(f"") # XXX: add message
499 #
500 # return self._valuePattern
502 def AsArgument(self) -> Union[str, Iterable[str]]:
503 """
504 Convert this argument instance to a sequence of string representations with proper escaping using the matching
505 pattern based on the internal name and value.
507 :return: Formatted argument as tuple of strings.
508 :raises ValueError: If internal name is None.
509 """
510 if self._name is None: 510 ↛ 511line 510 didn't jump to line 511 because the condition on line 510 was never true
511 raise ValueError(f"Internal value '_name' is None.")
513 return (
514 self._pattern.format(self._name),
515 self._valuePattern.format(self._value)
516 )
518 def __str__(self) -> str:
519 """
520 Return a string representation of this argument instance.
522 :return: Space separated sequence of arguments formatted and each enclosed in double quotes.
523 """
524 return " ".join([f"\"{item}\"" for item in self.AsArgument()])
526 def __repr__(self) -> str:
527 """
528 Return a string representation of this argument instance.
530 :return: Comma separated sequence of arguments formatted and each enclosed in double quotes.
531 """
532 return ", ".join([f"\"{item}\"" for item in self.AsArgument()])
535@export
536class StringArgument(ValuedArgument, pattern="{0}"):
537 """
538 Represents a simple string argument.
540 A list of strings is available as :class:`~pyTooling.CLIAbstraction.Argument.StringListArgument`.
541 """
543 def __init_subclass__(cls, *args: Any, pattern: str = "{0}", **kwargs: Any) -> None:
544 """
545 This method is called when a class is derived.
547 :param args: Any positional arguments.
548 :param pattern: This pattern is used to format an argument. |br|
549 Default: ``"{0}"``.
550 :param kwargs: Any keyword argument.
551 """
552 kwargs["pattern"] = pattern
553 super().__init_subclass__(*args, **kwargs)
556@export
557class StringListArgument(ValuedArgument):
558 """
559 Represents a list of string argument (:class:`~pyTooling.CLIAbstraction.Argument.StringArgument`)."""
561 def __init__(self, values: Iterable[str]) -> None:
562 """
563 Initializes a StringListArgument instance.
565 :param values: An iterable of str instances.
566 :raises TypeError: If iterable parameter 'values' contains elements not of type :class:`str`.
567 """
568 self._values = []
569 for value in values:
570 if not isinstance(value, str): 570 ↛ 571line 570 didn't jump to line 571 because the condition on line 570 was never true
571 ex = TypeError(f"Parameter 'values' contains elements which are not of type 'str'.")
572 ex.add_note(f"Got type '{getFullyQualifiedName(values)}'.")
573 raise ex
575 self._values.append(value)
577 @property
578 def Value(self) -> List[str]:
579 """
580 Get the internal list of str objects.
582 :return: Reference to the internal list of str objects.
583 """
584 return self._values
586 @Value.setter
587 def Value(self, value: Iterable[str]) -> None:
588 """
589 Overwrite all elements in the internal list of str objects.
591 .. note:: The list object is not replaced, but cleared and then reused by adding the given elements in the iterable.
593 :param value: List of str objects to set.
594 :raises TypeError: If value contains elements, which are not of type :class:`str`.
595 """
596 self._values.clear()
597 for value in value:
598 if not isinstance(value, str):
599 ex = TypeError(f"Value contains elements which are not of type 'str'.")
600 ex.add_note(f"Got type '{getFullyQualifiedName(value)}'.")
601 raise ex
602 self._values.append(value)
604 def AsArgument(self) -> Union[str, Iterable[str]]:
605 """
606 Convert this argument instance to a string representation with proper escaping using the matching pattern based on
607 the internal value.
609 :return: Sequence of formatted arguments.
610 """
611 return [f"{value}" for value in self._values]
613 def __str__(self) -> str:
614 """
615 Return a string representation of this argument instance.
617 :return: Space separated sequence of arguments formatted and each enclosed in double quotes.
618 """
619 return " ".join([f"\"{value}\"" for value in self.AsArgument()])
621 def __repr__(self) -> str:
622 """
623 Return a string representation of this argument instance.
625 :return: Comma separated sequence of arguments formatted and each enclosed in double quotes.
626 """
627 return ", ".join([f"\"{value}\"" for value in self.AsArgument()])
630# TODO: Add option to class if path should be checked for existence
631@export
632class PathArgument(CommandLineArgument):
633 """
634 Represents a single path argument.
636 A list of paths is available as :class:`~pyTooling.CLIAbstraction.Argument.PathListArgument`.
637 """
638 # The output format can be forced to the POSIX format with :py:data:`_PosixFormat`.
639 _path: Path
641 def __init__(self, path: Path) -> None:
642 """
643 Initializes a PathArgument instance.
645 :param path: Path to a filesystem object.
646 :raises TypeError: If parameter 'path' is not of type :class:`~pathlib.Path`.
647 """
648 if not isinstance(path, Path): 648 ↛ 649line 648 didn't jump to line 649 because the condition on line 648 was never true
649 ex = TypeError("Parameter 'path' is not of type 'Path'.")
650 ex.add_note(f"Got type '{getFullyQualifiedName(path)}'.")
651 raise ex
652 self._path = path
654 @property
655 def Value(self) -> Path:
656 """
657 Get the internal path object.
659 :return: Internal path object.
660 """
661 return self._path
663 @Value.setter
664 def Value(self, value: Path) -> None:
665 """
666 Set the internal path object.
668 :param value: Value to set.
669 :raises TypeError: If value is not of type :class:`~pathlib.Path`.
670 """
671 if not isinstance(value, Path): 671 ↛ 672line 671 didn't jump to line 672 because the condition on line 671 was never true
672 ex = TypeError("Value is not of type 'Path'.")
673 ex.add_note(f"Got type '{getFullyQualifiedName(value)}'.")
674 raise ex
676 self._path = value
678 def AsArgument(self) -> Union[str, Iterable[str]]:
679 """
680 Convert this argument instance to a string representation with proper escaping using the matching pattern based on
681 the internal value.
683 :return: Formatted argument.
684 """
685 return f"{self._path}"
687 def __str__(self) -> str:
688 """
689 Return a string representation of this argument instance.
691 :return: Argument formatted and enclosed in double quotes.
692 """
693 return f"\"{self._path}\""
695 __repr__ = __str__
698@export
699class PathListArgument(CommandLineArgument):
700 """
701 Represents a list of path arguments (:class:`~pyTooling.CLIAbstraction.Argument.PathArgument`).
702 """
703 # The output format can be forced to the POSIX format with :py:data:`_PosixFormat`.
704 _paths: List[Path]
706 def __init__(self, paths: Iterable[Path]) -> None:
707 """
708 Initializes a PathListArgument instance.
710 :param paths: An iterable os Path instances.
711 :raises TypeError: If iterable parameter 'paths' contains elements not of type :class:`~pathlib.Path`.
712 """
713 self._paths = []
714 for path in paths:
715 if not isinstance(path, Path): 715 ↛ 716line 715 didn't jump to line 716 because the condition on line 715 was never true
716 ex = TypeError(f"Parameter 'paths' contains elements which are not of type 'Path'.")
717 ex.add_note(f"Got type '{getFullyQualifiedName(path)}'.")
718 raise ex
720 self._paths.append(path)
722 @property
723 def Value(self) -> List[Path]:
724 """
725 Get the internal list of path objects.
727 :return: Reference to the internal list of path objects.
728 """
729 return self._paths
731 @Value.setter
732 def Value(self, value: Iterable[Path]) -> None:
733 """
734 Overwrite all elements in the internal list of path objects.
736 .. note:: The list object is not replaced, but cleared and then reused by adding the given elements in the iterable.
738 :param value: List of path objects to set.
739 :raises TypeError: If value contains elements, which are not of type :class:`~pathlib.Path`.
740 """
741 self._paths.clear()
742 for path in value:
743 if not isinstance(path, Path):
744 ex = TypeError(f"Value contains elements which are not of type 'Path'.")
745 ex.add_note(f"Got type '{getFullyQualifiedName(path)}'.")
746 raise ex
747 self._paths.append(path)
749 def AsArgument(self) -> Union[str, Iterable[str]]:
750 """
751 Convert this argument instance to a string representation with proper escaping using the matching pattern based on
752 the internal value.
754 :return: Sequence of formatted arguments.
755 """
756 return [f"{path}" for path in self._paths]
758 def __str__(self) -> str:
759 """
760 Return a string representation of this argument instance.
762 :return: Space separated sequence of arguments formatted and each enclosed in double quotes.
763 """
764 return " ".join([f"\"{value}\"" for value in self.AsArgument()])
766 def __repr__(self) -> str:
767 """
768 Return a string representation of this argument instance.
770 :return: Comma separated sequence of arguments formatted and each enclosed in double quotes.
771 """
772 return ", ".join([f"\"{value}\"" for value in self.AsArgument()])