@@ -245,6 +245,31 @@ class Signature(BaseModel, metaclass=SignatureMeta):
245245
246246 @classmethod
247247 def with_instructions (cls , instructions : str ) -> type ["Signature" ]:
248+ """Return a new Signature class with identical fields and new instructions.
249+
250+ This method does not mutate `cls`. It constructs a fresh Signature
251+ class using the current fields and the provided `instructions`.
252+
253+ Args:
254+ instructions (str): Instruction text to attach to the new signature.
255+
256+ Returns:
257+ A new Signature class whose fields match `cls.fields`
258+ and whose instructions equal `instructions`.
259+
260+ Example:
261+ ```python
262+ import dspy
263+
264+ class MySig(dspy.Signature):
265+ input_text: str = dspy.InputField(desc="Input text")
266+ output_text: str = dspy.OutputField(desc="Output text")
267+
268+ NewSig = MySig.with_instructions("Translate to French.")
269+ assert NewSig is not MySig
270+ assert NewSig.instructions == "Translate to French."
271+ ```
272+ """
248273 return Signature (cls .fields , instructions )
249274
250275 @classmethod
@@ -275,14 +300,87 @@ def with_updated_fields(cls, name: str, type_: type | None = None, **kwargs: dic
275300
276301 @classmethod
277302 def prepend (cls , name , field , type_ = None ) -> type ["Signature" ]:
303+ """Insert a field at index 0 of the `inputs` or `outputs` section.
304+
305+ Args:
306+ name (str): Field name to add.
307+ field: `InputField` or `OutputField` instance to insert.
308+ type_ (type | None): Optional explicit type annotation. If `type_` is `None`, the effective type is
309+ resolved by `insert`.
310+
311+ Returns:
312+ A new `Signature` class with the field inserted first.
313+
314+ Example:
315+ ```python
316+ import dspy
317+
318+ class MySig(dspy.Signature):
319+ input_text: str = dspy.InputField(desc="Input sentence")
320+ output_text: str = dspy.OutputField(desc="Translated sentence")
321+
322+ NewSig = MySig.prepend("context", dspy.InputField(desc="Context for translation"))
323+ print(list(NewSig.fields.keys()))
324+ ```
325+ """
278326 return cls .insert (0 , name , field , type_ )
279327
280328 @classmethod
281329 def append (cls , name , field , type_ = None ) -> type ["Signature" ]:
330+ """Insert a field at the end of the `inputs` or `outputs` section.
331+
332+ Args:
333+ name (str): Field name to add.
334+ field: `InputField` or `OutputField` instance to insert.
335+ type_ (type | None): Optional explicit type annotation. If `type_` is `None`, the effective type is
336+ resolved by `insert`.
337+
338+ Returns:
339+ A new Signature class with the field appended.
340+
341+ Example:
342+ ```python
343+ import dspy
344+
345+ class MySig(dspy.Signature):
346+ input_text: str = dspy.InputField(desc="Input sentence")
347+ output_text: str = dspy.OutputField(desc="Translated sentence")
348+
349+ NewSig = MySig.append("confidence", dspy.OutputField(desc="Translation confidence"))
350+ print(list(NewSig.fields.keys()))
351+ ```
352+ """
282353 return cls .insert (- 1 , name , field , type_ )
283354
284355 @classmethod
285356 def delete (cls , name ) -> type ["Signature" ]:
357+ """Return a new Signature class without the given field.
358+
359+ If `name` is not present, the fields are unchanged (no error raised).
360+
361+ Args:
362+ name (str): Field name to remove.
363+
364+ Returns:
365+ A new Signature class with the field removed (or unchanged if the field was absent).
366+
367+ Example:
368+ ```python
369+ import dspy
370+
371+ class MySig(dspy.Signature):
372+ input_text: str = dspy.InputField(desc="Input sentence")
373+ temp_field: str = dspy.InputField(desc="Temporary debug field")
374+ output_text: str = dspy.OutputField(desc="Translated sentence")
375+
376+ NewSig = MySig.delete("temp_field")
377+ print(list(NewSig.fields.keys()))
378+
379+ # No error is raised if the field is not present
380+ Unchanged = NewSig.delete("nonexistent")
381+ print(list(Unchanged.fields.keys()))
382+ ```
383+ """
286384 fields = dict (cls .fields )
287385
288386 fields .pop (name , None )
@@ -291,6 +389,38 @@ def delete(cls, name) -> type["Signature"]:
291389
292390 @classmethod
293391 def insert (cls , index : int , name : str , field , type_ : type | None = None ) -> type ["Signature" ]:
392+ """Insert a field at a specific position among inputs or outputs.
393+
394+ Negative indices are supported (e.g., `-1` appends). If `type_` is omitted, the field's
395+ existing `annotation` is used; if that is missing, `str` is used.
396+
397+ Args:
398+ index (int): Insertion position within the chosen section; negatives append.
399+ name (str): Field name to add.
400+ field: InputField or OutputField instance to insert.
401+ type_ (type | None): Optional explicit type annotation.
402+
403+ Returns:
404+ A new Signature class with the field inserted.
405+
406+ Raises:
407+ ValueError: If `index` falls outside the valid range for the chosen section.
408+
409+ Example:
410+ ```python
411+ import dspy
412+
413+ class MySig(dspy.Signature):
414+ input_text: str = dspy.InputField(desc="Input sentence")
415+ output_text: str = dspy.OutputField(desc="Translated sentence")
416+
417+ NewSig = MySig.insert(0, "context", dspy.InputField(desc="Context for translation"))
418+ print(list(NewSig.fields.keys()))
419+
420+ NewSig2 = NewSig.insert(-1, "confidence", dspy.OutputField(desc="Translation confidence"))
421+ print(list(NewSig2.fields.keys()))
422+ ```
423+ """
294424 # It's possible to set the type as annotation=type in pydantic.Field(...)
295425 # But this may be annoying for users, so we allow them to pass the type
296426 if type_ is None :
@@ -430,7 +560,9 @@ class MyType:
430560 # program of thought and teleprompters, so we just silently default to string.
431561 if type_ is None :
432562 type_ = str
433- if not isinstance (type_ , (type , typing ._GenericAlias , types .GenericAlias , typing ._SpecialForm , types .UnionType )):
563+ if not isinstance (
564+ type_ , (type , typing ._GenericAlias , types .GenericAlias , typing ._SpecialForm , types .UnionType )
565+ ):
434566 raise ValueError (f"Field types must be types, but received: { type_ } of type { type (type_ )} ." )
435567 if not isinstance (field , FieldInfo ):
436568 raise ValueError (f"Field values must be Field instances, but received: { field } ." )
0 commit comments