@@ -140,3 +140,114 @@ The signature can be passed in three different formats.
140140 .. code-block :: python
141141
142142 [" first_argument" , " second_argument" ]
143+
144+
145+ .. _how_to_parametrize_a_task_the_id :
146+
147+ The id
148+ ------
149+
150+ Every task has a unique id which can be used to :doc: `select it <how_to_select_tasks >`.
151+ The normal id combines the path to the module where the task is defined, a double colon,
152+ and the name of the task function. Here is an example.
153+
154+ .. code-block ::
155+
156+ ../task_example.py::task_example
157+
158+ This behavior would produce duplicate ids for parametrized tasks. Therefore, there exist
159+ multiple mechanisms to produce unique ids.
160+
161+
162+ Auto-generated ids
163+ ~~~~~~~~~~~~~~~~~~
164+
165+ To avoid duplicate task ids, the ids of parametrized tasks are extended with
166+ descriptions of the values they are parametrized with. Booleans, floats, integers and
167+ strings enter the task id directly. For example, a task function which receives four
168+ arguments, ``True ``, ``1.0 ``, ``2 ``, and ``"hello" ``, one of each dtype, has the
169+ following id.
170+
171+ .. code-block ::
172+
173+ task_example.py::task_example[True-1.0-2-hello]
174+
175+ Arguments with other dtypes cannot be easily converted to strings and, thus, are
176+ replaced with a combination of the argument name and the iteration counter.
177+
178+ For example, the following function is parametrized with tuples.
179+
180+ .. code-block :: python
181+
182+ @pytask.mark.parametrized (" i" , [(0 ,), (1 ,)])
183+ def task_example (i ):
184+ pass
185+
186+ Since the tuples are not converted to strings, the ids of the two tasks are
187+
188+ .. code-block ::
189+
190+ task_example.py::task_example[i0]
191+ task_example.py::task_example[i1]
192+
193+
194+ .. _how_to_parametrize_a_task_convert_other_objects :
195+
196+ Convert other objects
197+ ~~~~~~~~~~~~~~~~~~~~~
198+
199+ To change the representation of tuples and other objects, you can pass a function to the
200+ ``ids `` argument of the :func: `~_pytask.parametrize.parametrize ` decorator. The function
201+ is called for every argument and may return a boolean, number, or string which will be
202+ integrated into the id. For every other return, the auto-generated value is used.
203+
204+ To get a unique representation of a tuple, we can use the hash value.
205+
206+ .. code-block :: python
207+
208+ def tuple_to_hash (value ):
209+ if isinstance (value, tuple ):
210+ return hash (a)
211+
212+
213+ @pytask.mark.parametrized (" i" , [(0 ,), (1 ,)], ids = tuple_to_hash)
214+ def task_example (i ):
215+ pass
216+
217+ This produces the following ids:
218+
219+ .. code-block ::
220+
221+ task_example.py::task_example[3430018387555] # (0,)
222+ task_example.py::task_example[3430019387558] # (1,)
223+
224+
225+ User-defined ids
226+ ~~~~~~~~~~~~~~~~
227+
228+ Instead of a function, you can also pass a list or another iterable of id values via
229+ ``ids ``.
230+
231+ This code
232+
233+ .. code-block :: python
234+
235+ @pytask.mark.parametrized (" i" , [(0 ,), (1 ,)], ids = [" first" , " second" ])
236+ def task_example (i ):
237+ pass
238+
239+ produces these ids
240+
241+ .. code-block ::
242+
243+ task_example.py::task_example[first] # (0,)
244+ task_example.py::task_example[second] # (1,)
245+
246+ This is arguably the easiest way to change the representation of many objects at once
247+ while also producing ids which are easy to remember and type.
248+
249+
250+ Further reading
251+ ---------------
252+
253+ - :doc: `../how_to_guides/how_to_extend_parametrizations `.
0 commit comments