langchain-core 0.3.74__py3-none-any.whl → 0.3.76__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of langchain-core might be problematic. Click here for more details.
- langchain_core/_api/beta_decorator.py +18 -41
- langchain_core/_api/deprecation.py +20 -7
- langchain_core/_api/path.py +19 -2
- langchain_core/_import_utils.py +7 -0
- langchain_core/agents.py +10 -6
- langchain_core/beta/runnables/context.py +2 -3
- langchain_core/callbacks/base.py +11 -4
- langchain_core/callbacks/file.py +13 -2
- langchain_core/callbacks/manager.py +129 -78
- langchain_core/callbacks/usage.py +4 -2
- langchain_core/chat_history.py +10 -12
- langchain_core/document_loaders/base.py +34 -9
- langchain_core/document_loaders/langsmith.py +3 -0
- langchain_core/documents/base.py +36 -11
- langchain_core/documents/compressor.py +9 -6
- langchain_core/documents/transformers.py +4 -2
- langchain_core/embeddings/fake.py +8 -5
- langchain_core/env.py +2 -3
- langchain_core/example_selectors/base.py +12 -0
- langchain_core/exceptions.py +7 -0
- langchain_core/globals.py +17 -28
- langchain_core/indexing/api.py +56 -44
- langchain_core/indexing/base.py +7 -10
- langchain_core/indexing/in_memory.py +23 -3
- langchain_core/language_models/__init__.py +3 -2
- langchain_core/language_models/base.py +64 -39
- langchain_core/language_models/chat_models.py +130 -42
- langchain_core/language_models/fake_chat_models.py +10 -11
- langchain_core/language_models/llms.py +49 -17
- langchain_core/load/dump.py +5 -7
- langchain_core/load/load.py +15 -1
- langchain_core/load/serializable.py +38 -43
- langchain_core/memory.py +7 -3
- langchain_core/messages/ai.py +36 -16
- langchain_core/messages/base.py +13 -6
- langchain_core/messages/content_blocks.py +23 -2
- langchain_core/messages/human.py +2 -6
- langchain_core/messages/modifier.py +1 -1
- langchain_core/messages/system.py +2 -6
- langchain_core/messages/tool.py +36 -16
- langchain_core/messages/utils.py +198 -87
- langchain_core/output_parsers/base.py +5 -2
- langchain_core/output_parsers/json.py +4 -4
- langchain_core/output_parsers/list.py +7 -22
- langchain_core/output_parsers/openai_functions.py +3 -0
- langchain_core/output_parsers/openai_tools.py +8 -1
- langchain_core/output_parsers/pydantic.py +4 -0
- langchain_core/output_parsers/string.py +5 -1
- langchain_core/output_parsers/transform.py +2 -2
- langchain_core/output_parsers/xml.py +23 -22
- langchain_core/outputs/chat_generation.py +18 -7
- langchain_core/outputs/generation.py +14 -3
- langchain_core/outputs/llm_result.py +8 -1
- langchain_core/prompt_values.py +10 -4
- langchain_core/prompts/base.py +4 -9
- langchain_core/prompts/chat.py +88 -61
- langchain_core/prompts/dict.py +16 -8
- langchain_core/prompts/few_shot.py +9 -11
- langchain_core/prompts/few_shot_with_templates.py +5 -1
- langchain_core/prompts/image.py +12 -5
- langchain_core/prompts/message.py +5 -6
- langchain_core/prompts/pipeline.py +13 -8
- langchain_core/prompts/prompt.py +22 -8
- langchain_core/prompts/string.py +18 -10
- langchain_core/prompts/structured.py +7 -2
- langchain_core/rate_limiters.py +2 -2
- langchain_core/retrievers.py +7 -6
- langchain_core/runnables/base.py +842 -567
- langchain_core/runnables/branch.py +15 -20
- langchain_core/runnables/config.py +11 -17
- langchain_core/runnables/configurable.py +34 -19
- langchain_core/runnables/fallbacks.py +24 -17
- langchain_core/runnables/graph.py +47 -40
- langchain_core/runnables/graph_ascii.py +40 -17
- langchain_core/runnables/graph_mermaid.py +27 -15
- langchain_core/runnables/graph_png.py +27 -31
- langchain_core/runnables/history.py +56 -59
- langchain_core/runnables/passthrough.py +47 -24
- langchain_core/runnables/retry.py +10 -6
- langchain_core/runnables/router.py +10 -9
- langchain_core/runnables/schema.py +2 -0
- langchain_core/runnables/utils.py +51 -89
- langchain_core/stores.py +13 -25
- langchain_core/structured_query.py +3 -7
- langchain_core/sys_info.py +9 -8
- langchain_core/tools/base.py +30 -23
- langchain_core/tools/convert.py +24 -13
- langchain_core/tools/simple.py +35 -3
- langchain_core/tools/structured.py +26 -3
- langchain_core/tracers/_streaming.py +6 -7
- langchain_core/tracers/base.py +2 -2
- langchain_core/tracers/context.py +5 -1
- langchain_core/tracers/core.py +109 -39
- langchain_core/tracers/evaluation.py +22 -26
- langchain_core/tracers/event_stream.py +41 -28
- langchain_core/tracers/langchain.py +12 -3
- langchain_core/tracers/langchain_v1.py +10 -2
- langchain_core/tracers/log_stream.py +57 -18
- langchain_core/tracers/root_listeners.py +4 -20
- langchain_core/tracers/run_collector.py +6 -16
- langchain_core/tracers/schemas.py +5 -1
- langchain_core/utils/aiter.py +14 -6
- langchain_core/utils/env.py +3 -0
- langchain_core/utils/function_calling.py +49 -30
- langchain_core/utils/interactive_env.py +6 -2
- langchain_core/utils/iter.py +11 -3
- langchain_core/utils/json.py +5 -2
- langchain_core/utils/json_schema.py +15 -5
- langchain_core/utils/loading.py +5 -1
- langchain_core/utils/mustache.py +24 -15
- langchain_core/utils/pydantic.py +32 -4
- langchain_core/utils/utils.py +24 -8
- langchain_core/vectorstores/base.py +7 -20
- langchain_core/vectorstores/in_memory.py +18 -12
- langchain_core/vectorstores/utils.py +18 -12
- langchain_core/version.py +1 -1
- langchain_core-0.3.76.dist-info/METADATA +77 -0
- langchain_core-0.3.76.dist-info/RECORD +174 -0
- langchain_core-0.3.74.dist-info/METADATA +0 -108
- langchain_core-0.3.74.dist-info/RECORD +0 -174
- {langchain_core-0.3.74.dist-info → langchain_core-0.3.76.dist-info}/WHEEL +0 -0
- {langchain_core-0.3.74.dist-info → langchain_core-0.3.76.dist-info}/entry_points.txt +0 -0
|
@@ -96,22 +96,22 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
|
|
|
96
96
|
)
|
|
97
97
|
|
|
98
98
|
runnable = RunnableParallel(
|
|
99
|
-
origin=RunnablePassthrough(),
|
|
100
|
-
modified=lambda x: x+1
|
|
99
|
+
origin=RunnablePassthrough(), modified=lambda x: x + 1
|
|
101
100
|
)
|
|
102
101
|
|
|
103
|
-
runnable.invoke(1)
|
|
102
|
+
runnable.invoke(1) # {'origin': 1, 'modified': 2}
|
|
104
103
|
|
|
105
104
|
|
|
106
|
-
def fake_llm(prompt: str) -> str:
|
|
105
|
+
def fake_llm(prompt: str) -> str: # Fake LLM for the example
|
|
107
106
|
return "completion"
|
|
108
107
|
|
|
108
|
+
|
|
109
109
|
chain = RunnableLambda(fake_llm) | {
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
"original": RunnablePassthrough(), # Original LLM output
|
|
111
|
+
"parsed": lambda text: text[::-1], # Parsing logic
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
chain.invoke(
|
|
114
|
+
chain.invoke("hello") # {'original': 'completion', 'parsed': 'noitelpmoc'}
|
|
115
115
|
|
|
116
116
|
In some cases, it may be useful to pass the input through while adding some
|
|
117
117
|
keys to the output. In this case, you can use the `assign` method:
|
|
@@ -120,17 +120,19 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
|
|
|
120
120
|
|
|
121
121
|
from langchain_core.runnables import RunnablePassthrough
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
|
|
124
|
+
def fake_llm(prompt: str) -> str: # Fake LLM for the example
|
|
124
125
|
return "completion"
|
|
125
126
|
|
|
127
|
+
|
|
126
128
|
runnable = {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
"llm1": fake_llm,
|
|
130
|
+
"llm2": fake_llm,
|
|
129
131
|
} | RunnablePassthrough.assign(
|
|
130
|
-
total_chars=lambda inputs: len(inputs[
|
|
132
|
+
total_chars=lambda inputs: len(inputs["llm1"] + inputs["llm2"])
|
|
131
133
|
)
|
|
132
134
|
|
|
133
|
-
runnable.invoke(
|
|
135
|
+
runnable.invoke("hello")
|
|
134
136
|
# {'llm1': 'completion', 'llm2': 'completion', 'total_chars': 20}
|
|
135
137
|
|
|
136
138
|
"""
|
|
@@ -186,16 +188,21 @@ class RunnablePassthrough(RunnableSerializable[Other, Other]):
|
|
|
186
188
|
afunc = func
|
|
187
189
|
func = None
|
|
188
190
|
|
|
189
|
-
super().__init__(func=func, afunc=afunc, input_type=input_type, **kwargs)
|
|
191
|
+
super().__init__(func=func, afunc=afunc, input_type=input_type, **kwargs)
|
|
190
192
|
|
|
191
193
|
@classmethod
|
|
192
194
|
@override
|
|
193
195
|
def is_lc_serializable(cls) -> bool:
|
|
196
|
+
"""Return True as this class is serializable."""
|
|
194
197
|
return True
|
|
195
198
|
|
|
196
199
|
@classmethod
|
|
197
|
-
@override
|
|
198
200
|
def get_lc_namespace(cls) -> list[str]:
|
|
201
|
+
"""Get the namespace of the langchain object.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
``["langchain", "schema", "runnable"]``
|
|
205
|
+
"""
|
|
199
206
|
return ["langchain", "schema", "runnable"]
|
|
200
207
|
|
|
201
208
|
@property
|
|
@@ -378,11 +385,15 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
|
|
|
378
385
|
)
|
|
379
386
|
from langchain_core.runnables.base import RunnableLambda
|
|
380
387
|
|
|
388
|
+
|
|
381
389
|
def add_ten(x: dict[str, int]) -> dict[str, int]:
|
|
382
390
|
return {"added": x["input"] + 10}
|
|
383
391
|
|
|
392
|
+
|
|
384
393
|
mapper = RunnableParallel(
|
|
385
|
-
{
|
|
394
|
+
{
|
|
395
|
+
"add_step": RunnableLambda(add_ten),
|
|
396
|
+
}
|
|
386
397
|
)
|
|
387
398
|
|
|
388
399
|
runnable_assign = RunnableAssign(mapper)
|
|
@@ -406,16 +417,22 @@ class RunnableAssign(RunnableSerializable[dict[str, Any], dict[str, Any]]):
|
|
|
406
417
|
mapper: A ``RunnableParallel`` instance that will be used to transform the
|
|
407
418
|
input dictionary.
|
|
408
419
|
"""
|
|
409
|
-
super().__init__(mapper=mapper, **kwargs)
|
|
420
|
+
super().__init__(mapper=mapper, **kwargs)
|
|
410
421
|
|
|
411
422
|
@classmethod
|
|
412
423
|
@override
|
|
413
424
|
def is_lc_serializable(cls) -> bool:
|
|
425
|
+
"""Return True as this class is serializable."""
|
|
414
426
|
return True
|
|
415
427
|
|
|
416
428
|
@classmethod
|
|
417
429
|
@override
|
|
418
430
|
def get_lc_namespace(cls) -> list[str]:
|
|
431
|
+
"""Get the namespace of the langchain object.
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
``["langchain", "schema", "runnable"]``
|
|
435
|
+
"""
|
|
419
436
|
return ["langchain", "schema", "runnable"]
|
|
420
437
|
|
|
421
438
|
@override
|
|
@@ -688,13 +705,13 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
|
|
|
688
705
|
from langchain_core.runnables.passthrough import RunnablePick
|
|
689
706
|
|
|
690
707
|
input_data = {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
708
|
+
"name": "John",
|
|
709
|
+
"age": 30,
|
|
710
|
+
"city": "New York",
|
|
711
|
+
"country": "USA",
|
|
695
712
|
}
|
|
696
713
|
|
|
697
|
-
runnable = RunnablePick(keys=[
|
|
714
|
+
runnable = RunnablePick(keys=["name", "age"])
|
|
698
715
|
|
|
699
716
|
output_data = runnable.invoke(input_data)
|
|
700
717
|
|
|
@@ -710,17 +727,22 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
|
|
|
710
727
|
Args:
|
|
711
728
|
keys: A single key or a list of keys to pick from the input dictionary.
|
|
712
729
|
"""
|
|
713
|
-
super().__init__(keys=keys, **kwargs)
|
|
730
|
+
super().__init__(keys=keys, **kwargs)
|
|
714
731
|
|
|
715
732
|
@classmethod
|
|
716
733
|
@override
|
|
717
734
|
def is_lc_serializable(cls) -> bool:
|
|
735
|
+
"""Return True as this class is serializable."""
|
|
718
736
|
return True
|
|
719
737
|
|
|
720
738
|
@classmethod
|
|
721
739
|
@override
|
|
722
740
|
def get_lc_namespace(cls) -> list[str]:
|
|
723
|
-
"""Get the namespace of the langchain object.
|
|
741
|
+
"""Get the namespace of the langchain object.
|
|
742
|
+
|
|
743
|
+
Returns:
|
|
744
|
+
``["langchain", "schema", "runnable"]``
|
|
745
|
+
"""
|
|
724
746
|
return ["langchain", "schema", "runnable"]
|
|
725
747
|
|
|
726
748
|
@override
|
|
@@ -730,7 +752,8 @@ class RunnablePick(RunnableSerializable[dict[str, Any], dict[str, Any]]):
|
|
|
730
752
|
name = (
|
|
731
753
|
name
|
|
732
754
|
or self.name
|
|
733
|
-
or
|
|
755
|
+
or "RunnablePick"
|
|
756
|
+
f"<{','.join([self.keys] if isinstance(self.keys, str) else self.keys)}>"
|
|
734
757
|
)
|
|
735
758
|
return super().get_name(suffix, name=name)
|
|
736
759
|
|
|
@@ -47,7 +47,7 @@ class ExponentialJitterParams(TypedDict, total=False):
|
|
|
47
47
|
"""Random additional wait sampled from random.uniform(0, jitter)."""
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
class RunnableRetry(RunnableBindingBase[Input, Output]):
|
|
50
|
+
class RunnableRetry(RunnableBindingBase[Input, Output]): # type: ignore[no-redef]
|
|
51
51
|
"""Retry a Runnable if it fails.
|
|
52
52
|
|
|
53
53
|
RunnableRetry can be used to add retry logic to any object
|
|
@@ -66,17 +66,21 @@ class RunnableRetry(RunnableBindingBase[Input, Output]):
|
|
|
66
66
|
|
|
67
67
|
import time
|
|
68
68
|
|
|
69
|
+
|
|
69
70
|
def foo(input) -> None:
|
|
70
71
|
'''Fake function that raises an exception.'''
|
|
71
72
|
raise ValueError(f"Invoking foo failed. At time {time.time()}")
|
|
72
73
|
|
|
74
|
+
|
|
73
75
|
runnable = RunnableLambda(foo)
|
|
74
76
|
|
|
75
77
|
runnable_with_retries = runnable.with_retry(
|
|
76
|
-
retry_if_exception_type=(ValueError,),
|
|
77
|
-
wait_exponential_jitter=True,
|
|
78
|
-
stop_after_attempt=2,
|
|
79
|
-
exponential_jitter_params={
|
|
78
|
+
retry_if_exception_type=(ValueError,), # Retry only on ValueError
|
|
79
|
+
wait_exponential_jitter=True, # Add jitter to the exponential backoff
|
|
80
|
+
stop_after_attempt=2, # Try twice
|
|
81
|
+
exponential_jitter_params={
|
|
82
|
+
"initial": 2
|
|
83
|
+
}, # if desired, customize backoff
|
|
80
84
|
)
|
|
81
85
|
|
|
82
86
|
# The method invocation above is equivalent to the longer form below:
|
|
@@ -111,7 +115,7 @@ class RunnableRetry(RunnableBindingBase[Input, Output]):
|
|
|
111
115
|
chain = template | model
|
|
112
116
|
retryable_chain = chain.with_retry()
|
|
113
117
|
|
|
114
|
-
"""
|
|
118
|
+
"""
|
|
115
119
|
|
|
116
120
|
retry_exception_types: tuple[type[BaseException], ...] = (Exception,)
|
|
117
121
|
"""The exception types to retry on. By default all exceptions are retried.
|
|
@@ -38,15 +38,12 @@ if TYPE_CHECKING:
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
class RouterInput(TypedDict):
|
|
41
|
-
"""Router input.
|
|
42
|
-
|
|
43
|
-
Attributes:
|
|
44
|
-
key: The key to route on.
|
|
45
|
-
input: The input to pass to the selected Runnable.
|
|
46
|
-
"""
|
|
41
|
+
"""Router input."""
|
|
47
42
|
|
|
48
43
|
key: str
|
|
44
|
+
"""The key to route on."""
|
|
49
45
|
input: Any
|
|
46
|
+
"""The input to pass to the selected Runnable."""
|
|
50
47
|
|
|
51
48
|
|
|
52
49
|
class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
@@ -87,7 +84,7 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
87
84
|
Args:
|
|
88
85
|
runnables: A mapping of keys to Runnables.
|
|
89
86
|
"""
|
|
90
|
-
super().__init__(
|
|
87
|
+
super().__init__(
|
|
91
88
|
runnables={key: coerce_to_runnable(r) for key, r in runnables.items()}
|
|
92
89
|
)
|
|
93
90
|
|
|
@@ -98,13 +95,17 @@ class RouterRunnable(RunnableSerializable[RouterInput, Output]):
|
|
|
98
95
|
@classmethod
|
|
99
96
|
@override
|
|
100
97
|
def is_lc_serializable(cls) -> bool:
|
|
101
|
-
"""Return
|
|
98
|
+
"""Return True as this class is serializable."""
|
|
102
99
|
return True
|
|
103
100
|
|
|
104
101
|
@classmethod
|
|
105
102
|
@override
|
|
106
103
|
def get_lc_namespace(cls) -> list[str]:
|
|
107
|
-
"""Get the namespace of the langchain object.
|
|
104
|
+
"""Get the namespace of the langchain object.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
``["langchain", "schema", "runnable"]``
|
|
108
|
+
"""
|
|
108
109
|
return ["langchain", "schema", "runnable"]
|
|
109
110
|
|
|
110
111
|
@override
|
|
@@ -51,9 +51,11 @@ class BaseStreamEvent(TypedDict):
|
|
|
51
51
|
|
|
52
52
|
from langchain_core.runnables import RunnableLambda
|
|
53
53
|
|
|
54
|
+
|
|
54
55
|
async def reverse(s: str) -> str:
|
|
55
56
|
return s[::-1]
|
|
56
57
|
|
|
58
|
+
|
|
57
59
|
chain = RunnableLambda(func=reverse)
|
|
58
60
|
|
|
59
61
|
events = [event async for event in chain.astream_events("hello")]
|
|
@@ -122,7 +122,12 @@ def accepts_context(callable: Callable[..., Any]) -> bool: # noqa: A002
|
|
|
122
122
|
|
|
123
123
|
@lru_cache(maxsize=1)
|
|
124
124
|
def asyncio_accepts_context() -> bool:
|
|
125
|
-
"""Cache the result of checking if asyncio.create_task accepts a ``context`` arg.
|
|
125
|
+
"""Cache the result of checking if asyncio.create_task accepts a ``context`` arg.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
bool: True if ``asyncio.create_task`` accepts a context argument, False
|
|
129
|
+
otherwise.
|
|
130
|
+
"""
|
|
126
131
|
return accepts_context(asyncio.create_task)
|
|
127
132
|
|
|
128
133
|
|
|
@@ -160,14 +165,11 @@ class IsLocalDict(ast.NodeVisitor):
|
|
|
160
165
|
self.keys = keys
|
|
161
166
|
|
|
162
167
|
@override
|
|
163
|
-
def visit_Subscript(self, node: ast.Subscript) ->
|
|
168
|
+
def visit_Subscript(self, node: ast.Subscript) -> None:
|
|
164
169
|
"""Visit a subscript node.
|
|
165
170
|
|
|
166
171
|
Args:
|
|
167
172
|
node: The node to visit.
|
|
168
|
-
|
|
169
|
-
Returns:
|
|
170
|
-
Any: The result of the visit.
|
|
171
173
|
"""
|
|
172
174
|
if (
|
|
173
175
|
isinstance(node.ctx, ast.Load)
|
|
@@ -180,14 +182,11 @@ class IsLocalDict(ast.NodeVisitor):
|
|
|
180
182
|
self.keys.add(node.slice.value)
|
|
181
183
|
|
|
182
184
|
@override
|
|
183
|
-
def visit_Call(self, node: ast.Call) ->
|
|
185
|
+
def visit_Call(self, node: ast.Call) -> None:
|
|
184
186
|
"""Visit a call node.
|
|
185
187
|
|
|
186
188
|
Args:
|
|
187
189
|
node: The node to visit.
|
|
188
|
-
|
|
189
|
-
Returns:
|
|
190
|
-
Any: The result of the visit.
|
|
191
190
|
"""
|
|
192
191
|
if (
|
|
193
192
|
isinstance(node.func, ast.Attribute)
|
|
@@ -210,14 +209,11 @@ class IsFunctionArgDict(ast.NodeVisitor):
|
|
|
210
209
|
self.keys: set[str] = set()
|
|
211
210
|
|
|
212
211
|
@override
|
|
213
|
-
def visit_Lambda(self, node: ast.Lambda) ->
|
|
212
|
+
def visit_Lambda(self, node: ast.Lambda) -> None:
|
|
214
213
|
"""Visit a lambda function.
|
|
215
214
|
|
|
216
215
|
Args:
|
|
217
216
|
node: The node to visit.
|
|
218
|
-
|
|
219
|
-
Returns:
|
|
220
|
-
Any: The result of the visit.
|
|
221
217
|
"""
|
|
222
218
|
if not node.args.args:
|
|
223
219
|
return
|
|
@@ -225,14 +221,11 @@ class IsFunctionArgDict(ast.NodeVisitor):
|
|
|
225
221
|
IsLocalDict(input_arg_name, self.keys).visit(node.body)
|
|
226
222
|
|
|
227
223
|
@override
|
|
228
|
-
def visit_FunctionDef(self, node: ast.FunctionDef) ->
|
|
224
|
+
def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
|
|
229
225
|
"""Visit a function definition.
|
|
230
226
|
|
|
231
227
|
Args:
|
|
232
228
|
node: The node to visit.
|
|
233
|
-
|
|
234
|
-
Returns:
|
|
235
|
-
Any: The result of the visit.
|
|
236
229
|
"""
|
|
237
230
|
if not node.args.args:
|
|
238
231
|
return
|
|
@@ -240,14 +233,11 @@ class IsFunctionArgDict(ast.NodeVisitor):
|
|
|
240
233
|
IsLocalDict(input_arg_name, self.keys).visit(node)
|
|
241
234
|
|
|
242
235
|
@override
|
|
243
|
-
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) ->
|
|
236
|
+
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:
|
|
244
237
|
"""Visit an async function definition.
|
|
245
238
|
|
|
246
239
|
Args:
|
|
247
240
|
node: The node to visit.
|
|
248
|
-
|
|
249
|
-
Returns:
|
|
250
|
-
Any: The result of the visit.
|
|
251
241
|
"""
|
|
252
242
|
if not node.args.args:
|
|
253
243
|
return
|
|
@@ -264,14 +254,11 @@ class NonLocals(ast.NodeVisitor):
|
|
|
264
254
|
self.stores: set[str] = set()
|
|
265
255
|
|
|
266
256
|
@override
|
|
267
|
-
def visit_Name(self, node: ast.Name) ->
|
|
257
|
+
def visit_Name(self, node: ast.Name) -> None:
|
|
268
258
|
"""Visit a name node.
|
|
269
259
|
|
|
270
260
|
Args:
|
|
271
261
|
node: The node to visit.
|
|
272
|
-
|
|
273
|
-
Returns:
|
|
274
|
-
Any: The result of the visit.
|
|
275
262
|
"""
|
|
276
263
|
if isinstance(node.ctx, ast.Load):
|
|
277
264
|
self.loads.add(node.id)
|
|
@@ -279,14 +266,11 @@ class NonLocals(ast.NodeVisitor):
|
|
|
279
266
|
self.stores.add(node.id)
|
|
280
267
|
|
|
281
268
|
@override
|
|
282
|
-
def visit_Attribute(self, node: ast.Attribute) ->
|
|
269
|
+
def visit_Attribute(self, node: ast.Attribute) -> None:
|
|
283
270
|
"""Visit an attribute node.
|
|
284
271
|
|
|
285
272
|
Args:
|
|
286
273
|
node: The node to visit.
|
|
287
|
-
|
|
288
|
-
Returns:
|
|
289
|
-
Any: The result of the visit.
|
|
290
274
|
"""
|
|
291
275
|
if isinstance(node.ctx, ast.Load):
|
|
292
276
|
parent = node.value
|
|
@@ -321,42 +305,33 @@ class FunctionNonLocals(ast.NodeVisitor):
|
|
|
321
305
|
self.nonlocals: set[str] = set()
|
|
322
306
|
|
|
323
307
|
@override
|
|
324
|
-
def visit_FunctionDef(self, node: ast.FunctionDef) ->
|
|
308
|
+
def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
|
|
325
309
|
"""Visit a function definition.
|
|
326
310
|
|
|
327
311
|
Args:
|
|
328
312
|
node: The node to visit.
|
|
329
|
-
|
|
330
|
-
Returns:
|
|
331
|
-
Any: The result of the visit.
|
|
332
313
|
"""
|
|
333
314
|
visitor = NonLocals()
|
|
334
315
|
visitor.visit(node)
|
|
335
316
|
self.nonlocals.update(visitor.loads - visitor.stores)
|
|
336
317
|
|
|
337
318
|
@override
|
|
338
|
-
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) ->
|
|
319
|
+
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef) -> None:
|
|
339
320
|
"""Visit an async function definition.
|
|
340
321
|
|
|
341
322
|
Args:
|
|
342
323
|
node: The node to visit.
|
|
343
|
-
|
|
344
|
-
Returns:
|
|
345
|
-
Any: The result of the visit.
|
|
346
324
|
"""
|
|
347
325
|
visitor = NonLocals()
|
|
348
326
|
visitor.visit(node)
|
|
349
327
|
self.nonlocals.update(visitor.loads - visitor.stores)
|
|
350
328
|
|
|
351
329
|
@override
|
|
352
|
-
def visit_Lambda(self, node: ast.Lambda) ->
|
|
330
|
+
def visit_Lambda(self, node: ast.Lambda) -> None:
|
|
353
331
|
"""Visit a lambda function.
|
|
354
332
|
|
|
355
333
|
Args:
|
|
356
334
|
node: The node to visit.
|
|
357
|
-
|
|
358
|
-
Returns:
|
|
359
|
-
Any: The result of the visit.
|
|
360
335
|
"""
|
|
361
336
|
visitor = NonLocals()
|
|
362
337
|
visitor.visit(node)
|
|
@@ -372,14 +347,11 @@ class GetLambdaSource(ast.NodeVisitor):
|
|
|
372
347
|
self.count = 0
|
|
373
348
|
|
|
374
349
|
@override
|
|
375
|
-
def visit_Lambda(self, node: ast.Lambda) ->
|
|
350
|
+
def visit_Lambda(self, node: ast.Lambda) -> None:
|
|
376
351
|
"""Visit a lambda function.
|
|
377
352
|
|
|
378
353
|
Args:
|
|
379
354
|
node: The node to visit.
|
|
380
|
-
|
|
381
|
-
Returns:
|
|
382
|
-
Any: The result of the visit.
|
|
383
355
|
"""
|
|
384
356
|
self.count += 1
|
|
385
357
|
if hasattr(ast, "unparse"):
|
|
@@ -496,6 +468,9 @@ class AddableDict(dict[str, Any]):
|
|
|
496
468
|
|
|
497
469
|
Args:
|
|
498
470
|
other: The other dictionary to add.
|
|
471
|
+
|
|
472
|
+
Returns:
|
|
473
|
+
A dictionary that is the result of adding the two dictionaries.
|
|
499
474
|
"""
|
|
500
475
|
chunk = AddableDict(self)
|
|
501
476
|
for key in other:
|
|
@@ -514,6 +489,9 @@ class AddableDict(dict[str, Any]):
|
|
|
514
489
|
|
|
515
490
|
Args:
|
|
516
491
|
other: The other dictionary to be added to.
|
|
492
|
+
|
|
493
|
+
Returns:
|
|
494
|
+
A dictionary that is the result of adding the two dictionaries.
|
|
517
495
|
"""
|
|
518
496
|
chunk = AddableDict(other)
|
|
519
497
|
for key in self:
|
|
@@ -573,22 +551,18 @@ async def aadd(addables: AsyncIterable[Addable]) -> Optional[Addable]:
|
|
|
573
551
|
|
|
574
552
|
|
|
575
553
|
class ConfigurableField(NamedTuple):
|
|
576
|
-
"""Field that can be configured by the user.
|
|
577
|
-
|
|
578
|
-
Parameters:
|
|
579
|
-
id: The unique identifier of the field.
|
|
580
|
-
name: The name of the field. Defaults to None.
|
|
581
|
-
description: The description of the field. Defaults to None.
|
|
582
|
-
annotation: The annotation of the field. Defaults to None.
|
|
583
|
-
is_shared: Whether the field is shared. Defaults to False.
|
|
584
|
-
"""
|
|
554
|
+
"""Field that can be configured by the user."""
|
|
585
555
|
|
|
586
556
|
id: str
|
|
587
|
-
|
|
557
|
+
"""The unique identifier of the field."""
|
|
588
558
|
name: Optional[str] = None
|
|
559
|
+
"""The name of the field. Defaults to None."""
|
|
589
560
|
description: Optional[str] = None
|
|
561
|
+
"""The description of the field. Defaults to None."""
|
|
590
562
|
annotation: Optional[Any] = None
|
|
563
|
+
"""The annotation of the field. Defaults to None."""
|
|
591
564
|
is_shared: bool = False
|
|
565
|
+
"""Whether the field is shared. Defaults to False."""
|
|
592
566
|
|
|
593
567
|
@override
|
|
594
568
|
def __hash__(self) -> int:
|
|
@@ -596,24 +570,20 @@ class ConfigurableField(NamedTuple):
|
|
|
596
570
|
|
|
597
571
|
|
|
598
572
|
class ConfigurableFieldSingleOption(NamedTuple):
|
|
599
|
-
"""Field that can be configured by the user with a default value.
|
|
600
|
-
|
|
601
|
-
Parameters:
|
|
602
|
-
id: The unique identifier of the field.
|
|
603
|
-
options: The options for the field.
|
|
604
|
-
default: The default value for the field.
|
|
605
|
-
name: The name of the field. Defaults to None.
|
|
606
|
-
description: The description of the field. Defaults to None.
|
|
607
|
-
is_shared: Whether the field is shared. Defaults to False.
|
|
608
|
-
"""
|
|
573
|
+
"""Field that can be configured by the user with a default value."""
|
|
609
574
|
|
|
610
575
|
id: str
|
|
576
|
+
"""The unique identifier of the field."""
|
|
611
577
|
options: Mapping[str, Any]
|
|
578
|
+
"""The options for the field."""
|
|
612
579
|
default: str
|
|
613
|
-
|
|
580
|
+
"""The default value for the field."""
|
|
614
581
|
name: Optional[str] = None
|
|
582
|
+
"""The name of the field. Defaults to None."""
|
|
615
583
|
description: Optional[str] = None
|
|
584
|
+
"""The description of the field. Defaults to None."""
|
|
616
585
|
is_shared: bool = False
|
|
586
|
+
"""Whether the field is shared. Defaults to False."""
|
|
617
587
|
|
|
618
588
|
@override
|
|
619
589
|
def __hash__(self) -> int:
|
|
@@ -621,24 +591,20 @@ class ConfigurableFieldSingleOption(NamedTuple):
|
|
|
621
591
|
|
|
622
592
|
|
|
623
593
|
class ConfigurableFieldMultiOption(NamedTuple):
|
|
624
|
-
"""Field that can be configured by the user with multiple default values.
|
|
625
|
-
|
|
626
|
-
Parameters:
|
|
627
|
-
id: The unique identifier of the field.
|
|
628
|
-
options: The options for the field.
|
|
629
|
-
default: The default values for the field.
|
|
630
|
-
name: The name of the field. Defaults to None.
|
|
631
|
-
description: The description of the field. Defaults to None.
|
|
632
|
-
is_shared: Whether the field is shared. Defaults to False.
|
|
633
|
-
"""
|
|
594
|
+
"""Field that can be configured by the user with multiple default values."""
|
|
634
595
|
|
|
635
596
|
id: str
|
|
597
|
+
"""The unique identifier of the field."""
|
|
636
598
|
options: Mapping[str, Any]
|
|
599
|
+
"""The options for the field."""
|
|
637
600
|
default: Sequence[str]
|
|
638
|
-
|
|
601
|
+
"""The default values for the field."""
|
|
639
602
|
name: Optional[str] = None
|
|
603
|
+
"""The name of the field. Defaults to None."""
|
|
640
604
|
description: Optional[str] = None
|
|
605
|
+
"""The description of the field. Defaults to None."""
|
|
641
606
|
is_shared: bool = False
|
|
607
|
+
"""Whether the field is shared. Defaults to False."""
|
|
642
608
|
|
|
643
609
|
@override
|
|
644
610
|
def __hash__(self) -> int:
|
|
@@ -651,26 +617,22 @@ AnyConfigurableField = Union[
|
|
|
651
617
|
|
|
652
618
|
|
|
653
619
|
class ConfigurableFieldSpec(NamedTuple):
|
|
654
|
-
"""Field that can be configured by the user. It is a specification of a field.
|
|
655
|
-
|
|
656
|
-
Parameters:
|
|
657
|
-
id: The unique identifier of the field.
|
|
658
|
-
annotation: The annotation of the field.
|
|
659
|
-
name: The name of the field. Defaults to None.
|
|
660
|
-
description: The description of the field. Defaults to None.
|
|
661
|
-
default: The default value for the field. Defaults to None.
|
|
662
|
-
is_shared: Whether the field is shared. Defaults to False.
|
|
663
|
-
dependencies: The dependencies of the field. Defaults to None.
|
|
664
|
-
"""
|
|
620
|
+
"""Field that can be configured by the user. It is a specification of a field."""
|
|
665
621
|
|
|
666
622
|
id: str
|
|
623
|
+
"""The unique identifier of the field."""
|
|
667
624
|
annotation: Any
|
|
668
|
-
|
|
625
|
+
"""The annotation of the field."""
|
|
669
626
|
name: Optional[str] = None
|
|
627
|
+
"""The name of the field. Defaults to None."""
|
|
670
628
|
description: Optional[str] = None
|
|
629
|
+
"""The description of the field. Defaults to None."""
|
|
671
630
|
default: Any = None
|
|
631
|
+
"""The default value for the field. Defaults to None."""
|
|
672
632
|
is_shared: bool = False
|
|
633
|
+
"""Whether the field is shared. Defaults to False."""
|
|
673
634
|
dependencies: Optional[list[str]] = None
|
|
635
|
+
"""The dependencies of the field. Defaults to None."""
|
|
674
636
|
|
|
675
637
|
|
|
676
638
|
def get_unique_config_specs(
|