However, doing the above currently results in TypeError: 'PosixPath' object is not iterable. Most likely related to #345, but I'll send in a PR afterwards to fix this specific case in a way that might fix many others.
Implementation considerations
In short, always treat pathlib.Path as a str for TextSubstitution. Tracing the source code from IncludeLaunchDescription, these are the steps taken on the launch_description_source argument:
In IncludeLaunchDescription, if launch_description_source isn't an instance of LaunchDescriptionSource, wrap it in AnyLaunchDescriptionSource.
In AnyLaunchDescriptionSource, pass the launch_file_path to parent's __init__().
In LaunchDescriptionSource, set self.__location to normalize_to_list_of_substitutions(location).
It is in normalize_to_list_of_substitutions when the error occurs, as since pathlib.Path isn't a str nor Substitution, it attempts to cast it to an Iterable to normalize each item within it, which isn't valid.
My proposal and PR later:
def normalize_to_list_of_substitutions(subs: SomeSubstitutionsType) -> List[Substitution]:
"""Return a list of Substitutions given a variety of starting inputs."""
# Avoid recursive import
from ..substitutions import TextSubstitution
def normalize(x):
if isinstance(x, Substitution):
return x
if isinstance(x, str):
return TextSubstitution(text=x)
raise TypeError(
"Failed to normalize given item of type '{}', when only "
"'str' or 'launch.Substitution' were expected.".format(type(x)))
### >>> Insert
if isinstance(subs, Path):
return [TextSubstitution(text=str(subs.resolve()))]
### <<< End
if isinstance(subs, str):
return [TextSubstitution(text=subs)]
if is_a_subclass(subs, Substitution):
return [cast(Substitution, subs)]
return [normalize(y) for y in cast(Iterable, subs)]
Since normalize_to_list_of_substitutions is used in many places, simply casting pathlib.Path to str may fix a lot of things, where the previous behaviour was to attempt to cast it to Iterable and crash with TypeError as a result.
Feature request
Feature description
Currently, for
IncludeLaunchDescription
, I have to do this:It would be nicer if I could just pass in
pathlib.Path
without casting to string first:However, doing the above currently results in
TypeError: 'PosixPath' object is not iterable
. Most likely related to #345, but I'll send in a PR afterwards to fix this specific case in a way that might fix many others.Implementation considerations
In short, always treat
pathlib.Path
as astr
forTextSubstitution
. Tracing the source code fromIncludeLaunchDescription
, these are the steps taken on thelaunch_description_source
argument:IncludeLaunchDescription
, iflaunch_description_source
isn't an instance ofLaunchDescriptionSource
, wrap it inAnyLaunchDescriptionSource
.AnyLaunchDescriptionSource
, pass thelaunch_file_path
to parent's__init__()
.LaunchDescriptionSource
, setself.__location
tonormalize_to_list_of_substitutions(location)
.It is in
normalize_to_list_of_substitutions
when the error occurs, as sincepathlib.Path
isn't astr
norSubstitution
, it attempts to cast it to anIterable
to normalize each item within it, which isn't valid.My proposal and PR later:
Since
normalize_to_list_of_substitutions
is used in many places, simply castingpathlib.Path
tostr
may fix a lot of things, where the previous behaviour was to attempt to cast it toIterable
and crash withTypeError
as a result.