From: "Juraj Linkeš" <juraj.linkes@pantheon.tech>
To: Luca Vizzarro <luca.vizzarro@arm.com>, dev@dpdk.org
Cc: Jeremy Spewock <jspewock@iol.unh.edu>,
Paul Szczepanek <paul.szczepanek@arm.com>
Subject: Re: [PATCH v2 1/8] dts: add params manipulation module
Date: Thu, 6 Jun 2024 11:19:31 +0200 [thread overview]
Message-ID: <19574098-0ee0-4194-b11d-9d9e889fca21@pantheon.tech> (raw)
In-Reply-To: <20240509112057.1167947-2-luca.vizzarro@arm.com>
The docstrings are missing the Args: or Returns: sections.
On 9. 5. 2024 13:20, Luca Vizzarro wrote:
> This commit introduces a new "params" module, which adds a new way
> to manage command line parameters. The provided Params dataclass
> is able to read the fields of its child class and produce a string
> representation to supply to the command line. Any data structure
> that is intended to represent command line parameters can inherit it.
>
> The main purpose is to make it easier to represent data structures that
> map to parameters. Aiding quicker development, while minimising code
> bloat.
>
> Signed-off-by: Luca Vizzarro <luca.vizzarro@arm.com>
> Reviewed-by: Paul Szczepanek <paul.szczepanek@arm.com>
> ---
> dts/framework/params/__init__.py | 274 +++++++++++++++++++++++++++++++
> 1 file changed, 274 insertions(+)
> create mode 100644 dts/framework/params/__init__.py
>
> diff --git a/dts/framework/params/__init__.py b/dts/framework/params/__init__.py
> new file mode 100644
> index 0000000000..aa27e34357
> --- /dev/null
> +++ b/dts/framework/params/__init__.py
> @@ -0,0 +1,274 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2024 Arm Limited
> +
> +"""Parameter manipulation module.
> +
> +This module provides :class:`Params` which can be used to model any data structure
> +that is meant to represent any command parameters.
> +"""
This should probably end with command line parameters.
> +
> +from dataclasses import dataclass, fields
> +from enum import Flag
> +from typing import Any, Callable, Iterable, Literal, Reversible, TypedDict, cast
> +
> +from typing_extensions import Self
> +
> +#: Type for a function taking one argument.
> +FnPtr = Callable[[Any], Any]
> +#: Type for a switch parameter.
> +Switch = Literal[True, None]
> +#: Type for a yes/no switch parameter.
> +YesNoSwitch = Literal[True, False, None]
> +
> +
> +def _reduce_functions(funcs: Reversible[FnPtr]) -> FnPtr:
The static method in the other patch is called compose and does
essentially the same thing, right? Can we use the same name (or a
similar one)?
Also, what is the difference in approaches between the two patches (or,
more accurately, the reason behind the difference)? In the other patch,
we're returning a dict, here we're returning a function directly.
> + """Reduces an iterable of :attr:`FnPtr` from end to start to a composite function.
We should make the order of application the same as in the method in
other patch, so if we change the order in the first one, we should do
the same here.
> +
> + If the iterable is empty, the created function just returns its fed value back.
> + """
> +
> + def composite_function(value: Any):
The return type is missing.
> + for fn in reversed(funcs):
> + value = fn(value)
> + return value
> +
> + return composite_function
> +
> +
> +def convert_str(*funcs: FnPtr):
The return type is missing.
And maybe the name could be better, now it suggests to me that we're
converting the __str__ method, but we're actually replacing it, so maybe
replace_str() or modify_str()?
> + """Decorator that makes the ``__str__`` method a composite function created from its arguments.
This should mention that it's a class decorator (and that it replaces or
modifies the __str__() method).
> +
> + The :attr:`FnPtr`s fed to the decorator are executed from right to left
> + in the arguments list order.
> +
> + Example:
> + .. code:: python
> +
> + @convert_str(hex_from_flag_value)
> + class BitMask(enum.Flag):
> + A = auto()
> + B = auto()
> +
> + will allow ``BitMask`` to render as a hexadecimal value.
> + """
> +
> + def _class_decorator(original_class):
> + original_class.__str__ = _reduce_functions(funcs)
> + return original_class
> +
> + return _class_decorator
> +
> +
> +def comma_separated(values: Iterable[Any]) -> str:
> + """Converts an iterable in a comma-separated string."""
> + return ",".join([str(value).strip() for value in values if value is not None])
> +
> +
> +def bracketed(value: str) -> str:
> + """Adds round brackets to the input."""
> + return f"({value})"
> +
> +
> +def str_from_flag_value(flag: Flag) -> str:
> + """Returns the value from a :class:`enum.Flag` as a string."""
> + return str(flag.value)
> +
> +
> +def hex_from_flag_value(flag: Flag) -> str:
> + """Returns the value from a :class:`enum.Flag` converted to hexadecimal."""
> + return hex(flag.value)
> +
> +
> +class ParamsModifier(TypedDict, total=False):
> + """Params modifiers dict compatible with the :func:`dataclasses.field` metadata parameter."""
> +
> + #:
> + Params_value_only: bool
> + #:
> + Params_short: str
> + #:
> + Params_long: str
> + #:
> + Params_multiple: bool
> + #:
> + Params_convert_value: Reversible[FnPtr]
> +
> +
> +@dataclass
> +class Params:
> + """Dataclass that renders its fields into command line arguments.
> +
> + The parameter name is taken from the field name by default. The following:
> +
> + .. code:: python
> +
> + name: str | None = "value"
> +
> + is rendered as ``--name=value``.
> + Through :func:`dataclasses.field` the resulting parameter can be manipulated by applying
> + this class' metadata modifier functions.
> +
> + To use fields as switches, set the value to ``True`` to render them. If you
> + use a yes/no switch you can also set ``False`` which would render a switch
> + prefixed with ``--no-``. Examples:
> +
> + .. code:: python
> +
> + interactive: Switch = True # renders --interactive
> + numa: YesNoSwitch = False # renders --no-numa
> +
> + Setting ``None`` will prevent it from being rendered. The :attr:`~Switch` type alias is provided
> + for regular switches, whereas :attr:`~YesNoSwitch` is offered for yes/no ones.
> +
> + An instance of a dataclass inheriting ``Params`` can also be assigned to an attribute,
> + this helps with grouping parameters together.
> + The attribute holding the dataclass will be ignored and the latter will just be rendered as
> + expected.
> + """
> +
> + _suffix = ""
> + """Holder of the plain text value of Params when called directly. A suffix for child classes."""
> +
> + """========= BEGIN FIELD METADATA MODIFIER FUNCTIONS ========"""
> +
> + @staticmethod
> + def value_only() -> ParamsModifier:
As far as I (or my IDE) can tell, this is not used anywhere. What's the
purpose of this?
> + """Injects the value of the attribute as-is without flag.
> +
> + Metadata modifier for :func:`dataclasses.field`.
> + """
> + return ParamsModifier(Params_value_only=True)
> +
> + @staticmethod
> + def short(name: str) -> ParamsModifier:
> + """Overrides any parameter name with the given short option.
> +
> + Metadata modifier for :func:`dataclasses.field`.
> +
> + Example:
> + .. code:: python
> +
> + logical_cores: str | None = field(default="1-4", metadata=Params.short("l"))
> +
> + will render as ``-l=1-4`` instead of ``--logical-cores=1-4``.
> + """
> + return ParamsModifier(Params_short=name)
> +
> + @staticmethod
> + def long(name: str) -> ParamsModifier:
> + """Overrides the inferred parameter name to the specified one.
> +
> + Metadata modifier for :func:`dataclasses.field`.
> +
> + Example:
> + .. code:: python
> +
> + x_name: str | None = field(default="y", metadata=Params.long("x"))
> +
> + will render as ``--x=y``, but the field is accessed and modified through ``x_name``.
> + """
> + return ParamsModifier(Params_long=name)
> +
> + @staticmethod
> + def multiple() -> ParamsModifier:
> + """Specifies that this parameter is set multiple times. Must be a list.
> +
> + Metadata modifier for :func:`dataclasses.field`.
> +
> + Example:
> + .. code:: python
> +
> + ports: list[int] | None = field(
> + default_factory=lambda: [0, 1, 2],
> + metadata=Params.multiple() | Params.long("port")
> + )
> +
> + will render as ``--port=0 --port=1 --port=2``. Note that modifiers can be chained like
> + in this example.
I'd put the explanation of how modifiers can be chained (and mention
they're dicts so the or operator just merges the dicts) into the class
docstring. Then we won't have to duplicate the explanation in each method.
> + """
> + return ParamsModifier(Params_multiple=True)
> +
> + @classmethod
> + def convert_value(cls, *funcs: FnPtr) -> ParamsModifier:
I don't see cls used anywhere, so let's make this static.
> + """Takes in a variable number of functions to convert the value text representation.
> +
> + Metadata modifier for :func:`dataclasses.field`.
> +
> + The ``metadata`` keyword argument can be used to chain metadata modifiers together.
> +
> + Functions can be chained together, executed from right to left in the arguments list order.
> +
> + Example:
> + .. code:: python
> +
> + hex_bitmask: int | None = field(
> + default=0b1101,
> + metadata=Params.convert_value(hex) | Params.long("mask")
> + )
> +
> + will render as ``--mask=0xd``.
> + """
> + return ParamsModifier(Params_convert_value=funcs)
> +
> + """========= END FIELD METADATA MODIFIER FUNCTIONS ========"""
> +
> + def append_str(self, text: str) -> None:
> + """Appends a string at the end of the string representation."""
> + self._suffix += text
> +
> + def __iadd__(self, text: str) -> Self:
> + """Appends a string at the end of the string representation."""
> + self.append_str(text)
> + return self
> +
> + @classmethod
> + def from_str(cls, text: str) -> Self:
I tried to figure out how self._suffix is used and I ended up finding
out this method is not used anywhere. Is that correct? If it's not used,
let's remove it.
What actually should be the suffix? A an arbitrary string that gets
appended to the rendered command line arguments? I guess this would be
here so that we can pass an already rendered string?
> + """Creates a plain Params object from a string."""
> + obj = cls()
> + obj.append_str(text)
> + return obj
> +
> + @staticmethod
> + def _make_switch(
> + name: str, is_short: bool = False, is_no: bool = False, value: str | None = None
> + ) -> str:
> + prefix = f"{'-' if is_short else '--'}{'no-' if is_no else ''}"
Does is_short work with is_no (that is, if both are True)? Do we need to
worry about it if not?
> + name = name.replace("_", "-")
> + value = f"{' ' if is_short else '='}{value}" if value else ""
> + return f"{prefix}{name}{value}"
> +
> + def __str__(self) -> str:
> + """Returns a string of command-line-ready arguments from the class fields."""
> + arguments: list[str] = []
> +
> + for field in fields(self):
> + value = getattr(self, field.name)
> + modifiers = cast(ParamsModifier, field.metadata)
> +
> + if value is None:
> + continue
> +
> + value_only = modifiers.get("Params_value_only", False)
> + if isinstance(value, Params) or value_only:
> + arguments.append(str(value))
> + continue
> +
> + # take the short modifier, or the long modifier, or infer from field name
> + switch_name = modifiers.get("Params_short", modifiers.get("Params_long", field.name))
> + is_short = "Params_short" in modifiers
> +
> + if isinstance(value, bool):
> + arguments.append(self._make_switch(switch_name, is_short, is_no=(not value)))
> + continue
> +
> + convert = _reduce_functions(modifiers.get("Params_convert_value", []))
> + multiple = modifiers.get("Params_multiple", False)
> +
> + values = value if multiple else [value]
> + for value in values:
> + arguments.append(self._make_switch(switch_name, is_short, value=convert(value)))
> +
> + if self._suffix:
> + arguments.append(self._suffix)
> +
> + return " ".join(arguments)
next prev parent reply other threads:[~2024-06-06 9:19 UTC|newest]
Thread overview: 159+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-26 19:04 [PATCH 0/6] dts: add testpmd params and statefulness Luca Vizzarro
2024-03-26 19:04 ` [PATCH 1/6] dts: add parameters data structure Luca Vizzarro
2024-03-28 16:48 ` Jeremy Spewock
2024-04-09 15:52 ` Luca Vizzarro
2024-04-09 12:10 ` Juraj Linkeš
2024-04-09 16:28 ` Luca Vizzarro
2024-04-10 9:15 ` Juraj Linkeš
2024-04-10 9:51 ` Luca Vizzarro
2024-04-10 10:04 ` Juraj Linkeš
2024-03-26 19:04 ` [PATCH 2/6] dts: use Params for interactive shells Luca Vizzarro
2024-03-28 16:48 ` Jeremy Spewock
2024-04-09 14:56 ` Juraj Linkeš
2024-04-10 9:34 ` Luca Vizzarro
2024-04-10 9:58 ` Juraj Linkeš
2024-05-28 15:43 ` Nicholas Pratte
2024-03-26 19:04 ` [PATCH 3/6] dts: add testpmd shell params Luca Vizzarro
2024-03-28 16:48 ` Jeremy Spewock
2024-04-09 16:37 ` Juraj Linkeš
2024-04-10 10:49 ` Luca Vizzarro
2024-04-10 13:17 ` Juraj Linkeš
2024-03-26 19:04 ` [PATCH 4/6] dts: use testpmd params for scatter test suite Luca Vizzarro
2024-04-09 19:12 ` Juraj Linkeš
2024-04-10 10:53 ` Luca Vizzarro
2024-04-10 13:18 ` Juraj Linkeš
2024-04-26 18:06 ` Jeremy Spewock
2024-04-29 7:45 ` Juraj Linkeš
2024-03-26 19:04 ` [PATCH 5/6] dts: add statefulness to InteractiveShell Luca Vizzarro
2024-03-28 16:48 ` Jeremy Spewock
2024-04-10 6:53 ` Juraj Linkeš
2024-04-10 11:27 ` Luca Vizzarro
2024-04-10 13:35 ` Juraj Linkeš
2024-04-10 14:07 ` Luca Vizzarro
2024-04-12 12:33 ` Juraj Linkeš
2024-04-29 14:48 ` Jeremy Spewock
2024-03-26 19:04 ` [PATCH 6/6] dts: add statefulness to TestPmdShell Luca Vizzarro
2024-03-28 16:48 ` Jeremy Spewock
2024-04-10 7:41 ` Juraj Linkeš
2024-04-10 11:35 ` Luca Vizzarro
2024-04-11 10:30 ` Juraj Linkeš
2024-04-11 11:47 ` Luca Vizzarro
2024-04-11 12:13 ` Juraj Linkeš
2024-04-11 13:59 ` Luca Vizzarro
2024-04-26 18:06 ` Jeremy Spewock
2024-04-29 12:06 ` Juraj Linkeš
2024-04-10 7:50 ` Juraj Linkeš
2024-04-10 11:37 ` Luca Vizzarro
2024-05-09 11:20 ` [PATCH v2 0/8] dts: add testpmd params Luca Vizzarro
2024-05-09 11:20 ` [PATCH v2 1/8] dts: add params manipulation module Luca Vizzarro
2024-05-28 15:40 ` Nicholas Pratte
2024-05-28 21:08 ` Jeremy Spewock
2024-06-06 9:19 ` Juraj Linkeš [this message]
2024-06-17 11:44 ` Luca Vizzarro
2024-06-18 8:55 ` Juraj Linkeš
2024-05-09 11:20 ` [PATCH v2 2/8] dts: use Params for interactive shells Luca Vizzarro
2024-05-28 17:43 ` Nicholas Pratte
2024-05-28 21:04 ` Jeremy Spewock
2024-06-06 13:14 ` Juraj Linkeš
2024-05-09 11:20 ` [PATCH v2 3/8] dts: refactor EalParams Luca Vizzarro
2024-05-28 15:44 ` Nicholas Pratte
2024-05-28 21:05 ` Jeremy Spewock
2024-06-06 13:17 ` Juraj Linkeš
2024-05-09 11:20 ` [PATCH v2 4/8] dts: remove module-wide imports Luca Vizzarro
2024-05-28 15:45 ` Nicholas Pratte
2024-05-28 21:08 ` Jeremy Spewock
2024-06-06 13:21 ` Juraj Linkeš
2024-05-09 11:20 ` [PATCH v2 5/8] dts: add testpmd shell params Luca Vizzarro
2024-05-28 15:53 ` Nicholas Pratte
2024-05-28 21:05 ` Jeremy Spewock
2024-05-29 15:59 ` Luca Vizzarro
2024-05-29 17:11 ` Jeremy Spewock
2024-05-09 11:20 ` [PATCH v2 6/8] dts: use testpmd params for scatter test suite Luca Vizzarro
2024-05-28 15:49 ` Nicholas Pratte
2024-05-28 21:06 ` Jeremy Spewock
2024-05-09 11:20 ` [PATCH v2 7/8] dts: rework interactive shells Luca Vizzarro
2024-05-28 15:50 ` Nicholas Pratte
2024-05-28 21:07 ` Jeremy Spewock
2024-05-29 15:57 ` Luca Vizzarro
2024-05-09 11:20 ` [PATCH v2 8/8] dts: use Unpack for type checking and hinting Luca Vizzarro
2024-05-28 15:50 ` Nicholas Pratte
2024-05-28 21:08 ` Jeremy Spewock
2024-05-22 15:59 ` [PATCH v2 0/8] dts: add testpmd params Nicholas Pratte
2024-05-30 15:24 ` [PATCH v3 " Luca Vizzarro
2024-05-30 15:24 ` [PATCH v3 1/8] dts: add params manipulation module Luca Vizzarro
2024-05-30 20:12 ` Jeremy Spewock
2024-05-31 15:19 ` Nicholas Pratte
2024-05-30 15:24 ` [PATCH v3 2/8] dts: use Params for interactive shells Luca Vizzarro
2024-05-30 20:12 ` Jeremy Spewock
2024-05-31 15:20 ` Nicholas Pratte
2024-05-30 15:25 ` [PATCH v3 3/8] dts: refactor EalParams Luca Vizzarro
2024-05-30 20:12 ` Jeremy Spewock
2024-05-31 15:21 ` Nicholas Pratte
2024-05-30 15:25 ` [PATCH v3 4/8] dts: remove module-wide imports Luca Vizzarro
2024-05-30 20:12 ` Jeremy Spewock
2024-05-31 15:21 ` Nicholas Pratte
2024-05-30 15:25 ` [PATCH v3 5/8] dts: add testpmd shell params Luca Vizzarro
2024-05-30 20:12 ` Jeremy Spewock
2024-05-31 15:20 ` Nicholas Pratte
2024-06-06 14:37 ` Juraj Linkeš
2024-05-30 15:25 ` [PATCH v3 6/8] dts: use testpmd params for scatter test suite Luca Vizzarro
2024-05-30 20:13 ` Jeremy Spewock
2024-05-31 15:22 ` Nicholas Pratte
2024-06-06 14:38 ` Juraj Linkeš
2024-05-30 15:25 ` [PATCH v3 7/8] dts: rework interactive shells Luca Vizzarro
2024-05-30 20:13 ` Jeremy Spewock
2024-05-31 15:22 ` Nicholas Pratte
2024-06-06 18:03 ` Juraj Linkeš
2024-06-17 12:13 ` Luca Vizzarro
2024-06-18 9:18 ` Juraj Linkeš
2024-05-30 15:25 ` [PATCH v3 8/8] dts: use Unpack for type checking and hinting Luca Vizzarro
2024-05-30 20:13 ` Jeremy Spewock
2024-05-31 15:21 ` Nicholas Pratte
2024-06-06 18:05 ` Juraj Linkeš
2024-06-17 14:42 ` [PATCH v4 0/8] dts: add testpmd params and statefulness Luca Vizzarro
2024-06-17 14:42 ` [PATCH v4 1/8] dts: add params manipulation module Luca Vizzarro
2024-06-17 14:42 ` [PATCH v4 2/8] dts: use Params for interactive shells Luca Vizzarro
2024-06-17 14:42 ` [PATCH v4 3/8] dts: refactor EalParams Luca Vizzarro
2024-06-17 14:42 ` [PATCH v4 4/8] dts: remove module-wide imports Luca Vizzarro
2024-06-17 14:42 ` [PATCH v4 5/8] dts: add testpmd shell params Luca Vizzarro
2024-06-17 14:42 ` [PATCH v4 6/8] dts: use testpmd params for scatter test suite Luca Vizzarro
2024-06-17 14:42 ` [PATCH v4 7/8] dts: rework interactive shells Luca Vizzarro
2024-06-17 14:42 ` [PATCH v4 8/8] dts: use Unpack for type checking and hinting Luca Vizzarro
2024-06-17 14:54 ` [PATCH v5 0/8] dts: add testpmd params Luca Vizzarro
2024-06-17 14:54 ` [PATCH v5 1/8] dts: add params manipulation module Luca Vizzarro
2024-06-17 15:22 ` Nicholas Pratte
2024-06-17 14:54 ` [PATCH v5 2/8] dts: use Params for interactive shells Luca Vizzarro
2024-06-17 15:23 ` Nicholas Pratte
2024-06-17 14:54 ` [PATCH v5 3/8] dts: refactor EalParams Luca Vizzarro
2024-06-17 15:23 ` Nicholas Pratte
2024-06-17 14:54 ` [PATCH v5 4/8] dts: remove module-wide imports Luca Vizzarro
2024-06-17 15:23 ` Nicholas Pratte
2024-06-17 14:54 ` [PATCH v5 5/8] dts: add testpmd shell params Luca Vizzarro
2024-06-17 15:24 ` Nicholas Pratte
2024-06-17 14:54 ` [PATCH v5 6/8] dts: use testpmd params for scatter test suite Luca Vizzarro
2024-06-17 15:24 ` Nicholas Pratte
2024-06-17 14:54 ` [PATCH v5 7/8] dts: rework interactive shells Luca Vizzarro
2024-06-17 15:25 ` Nicholas Pratte
2024-06-17 14:54 ` [PATCH v5 8/8] dts: use Unpack for type checking and hinting Luca Vizzarro
2024-06-17 15:25 ` Nicholas Pratte
2024-06-19 10:23 ` [PATCH v6 0/8] dts: add testpmd params Luca Vizzarro
2024-06-19 10:23 ` [PATCH v6 1/8] dts: add params manipulation module Luca Vizzarro
2024-06-19 12:45 ` Juraj Linkeš
2024-06-19 10:23 ` [PATCH v6 2/8] dts: use Params for interactive shells Luca Vizzarro
2024-06-19 10:23 ` [PATCH v6 3/8] dts: refactor EalParams Luca Vizzarro
2024-06-19 10:23 ` [PATCH v6 4/8] dts: remove module-wide imports Luca Vizzarro
2024-06-19 10:23 ` [PATCH v6 5/8] dts: add testpmd shell params Luca Vizzarro
2024-06-19 10:23 ` [PATCH v6 6/8] dts: use testpmd params for scatter test suite Luca Vizzarro
2024-06-19 10:23 ` [PATCH v6 7/8] dts: rework interactive shells Luca Vizzarro
2024-06-19 12:49 ` Juraj Linkeš
2024-06-19 10:23 ` [PATCH v6 8/8] dts: use Unpack for type checking and hinting Luca Vizzarro
2024-06-19 14:02 ` [PATCH v7 0/8] dts: add testpmd params Luca Vizzarro
2024-06-19 14:02 ` [PATCH v7 1/8] dts: add params manipulation module Luca Vizzarro
2024-06-19 14:02 ` [PATCH v7 2/8] dts: use Params for interactive shells Luca Vizzarro
2024-06-19 14:03 ` [PATCH v7 3/8] dts: refactor EalParams Luca Vizzarro
2024-06-19 14:03 ` [PATCH v7 4/8] dts: remove module-wide imports Luca Vizzarro
2024-06-19 14:03 ` [PATCH v7 5/8] dts: add testpmd shell params Luca Vizzarro
2024-06-19 14:03 ` [PATCH v7 6/8] dts: use testpmd params for scatter test suite Luca Vizzarro
2024-06-19 14:03 ` [PATCH v7 7/8] dts: rework interactive shells Luca Vizzarro
2024-06-19 14:03 ` [PATCH v7 8/8] dts: use Unpack for type checking and hinting Luca Vizzarro
2024-06-20 3:36 ` [PATCH v7 0/8] dts: add testpmd params Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=19574098-0ee0-4194-b11d-9d9e889fca21@pantheon.tech \
--to=juraj.linkes@pantheon.tech \
--cc=dev@dpdk.org \
--cc=jspewock@iol.unh.edu \
--cc=luca.vizzarro@arm.com \
--cc=paul.szczepanek@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).