Skip to content

Commit a257112

Browse files
nicolas-gauthier-sonarsourcesonartech
authored andcommitted
SONARPY-3296 Implement support for Langchain in S7693 (#548)
GitOrigin-RevId: 6f869848853e50be065ae5cb257c74c3691001d0
1 parent 26c557f commit a257112

11 files changed

Lines changed: 461 additions & 3 deletions

File tree

python-checks/src/main/java/org/sonar/python/checks/utils/CheckUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.sonar.python.api.PythonTokenType;
4444
import org.sonar.python.tree.TreeUtils;
4545

46+
import static org.sonar.plugins.python.api.tree.Tree.Kind.DICTIONARY_LITERAL;
4647
import static org.sonar.plugins.python.api.tree.Tree.Kind.GENERATOR_EXPR;
4748
import static org.sonar.plugins.python.api.tree.Tree.Kind.LAMBDA;
4849
import static org.sonar.plugins.python.api.tree.Tree.Kind.NAME;
@@ -144,6 +145,19 @@ public static Optional<StringLiteral> extractStringLiteral(Tree tree) {
144145
return Optional.empty();
145146
}
146147

148+
public static Optional<DictionaryLiteral> extractDict(Tree tree) {
149+
if (tree.is(DICTIONARY_LITERAL)) {
150+
return Optional.of((DictionaryLiteral) tree);
151+
}
152+
if (tree.is(NAME)) {
153+
Expression assignedValue = Expressions.singleAssignedValue(((Name) tree));
154+
if (assignedValue != null && assignedValue.is(DICTIONARY_LITERAL)) {
155+
return Optional.of((DictionaryLiteral) assignedValue);
156+
}
157+
}
158+
return Optional.empty();
159+
}
160+
147161
public static boolean isConstant(Expression condition) {
148162
return isImmutableConstant(condition) || isConstantCollectionLiteral(condition);
149163
}

python-checks/src/test/java/org/sonar/python/checks/utils/CheckUtilsTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,27 @@ void hasStringLiteralValueTest() {
194194
});
195195
}
196196

197+
@Test
198+
void extractDictTest() {
199+
var fileInput = parseFileWithSymbols("src/test/resources/checks/checkUtils/extractDictTest.py");
200+
List<Statement> statements = fileInput.statements().statements();
201+
assertThat(statements.get(0)).isInstanceOfSatisfying(AssignmentStatement.class, expressionStatement -> {
202+
assertThat(CheckUtils.extractDict(expressionStatement.assignedValue())).isPresent();
203+
});
204+
assertThat(statements.get(1)).isInstanceOfSatisfying(ExpressionStatement.class, expressionStatement -> {
205+
assertThat(CheckUtils.extractDict(expressionStatement.expressions().get(0))).isPresent();
206+
});
207+
assertThat(statements.get(2)).isInstanceOfSatisfying(ExpressionStatement.class, expressionStatement -> {
208+
assertThat(CheckUtils.extractDict(expressionStatement.expressions().get(0))).isEmpty();
209+
});
210+
assertThat(statements.get(3)).isInstanceOfSatisfying(AssignmentStatement.class, expressionStatement -> {
211+
assertThat(CheckUtils.extractDict(expressionStatement.assignedValue())).isEmpty();
212+
});
213+
assertThat(statements.get(4)).isInstanceOfSatisfying(ExpressionStatement.class, expressionStatement -> {
214+
assertThat(CheckUtils.extractDict(expressionStatement.expressions().get(0))).isEmpty();
215+
});
216+
}
217+
197218
@Test
198219
void isAbstractTest() throws IOException {
199220
var fileInput = parseFile("src/test/resources/checks/checkUtils/isAbstractTest.py");
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
dictionary = {"key": "value"}
2+
dictionary
3+
unknownDictionnary
4+
notDictionnary = 1
5+
notDictionnary

python-frontend/src/main/resources/org/sonar/python/types/custom_protobuf/langchain_aws.chat_models.bedrock_converse.protobuf

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
2+
*langchain_aws.chat_models.bedrock_converse�;
3+
ChatBedrockConverse>langchain_aws.chat_models.bedrock_converse.ChatBedrockConverse"*SonarPythonAnalyzerFakeStub.CustomStubBaser�
4+
additional_model_request_fields^langchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.additional_model_request_fields�
5+
+Union[builtins.dict[builtins.str,Any],None]W
6+
builtins.dict[builtins.str,Any]
7+
builtins.str" builtins.str
8+
Any"builtins.dict
9+
Noner�
10+
%additional_model_response_field_pathsdlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.additional_model_response_field_paths�
11+
'Union[builtins.list[builtins.str],None]J
12+
builtins.list[builtins.str]
13+
builtins.str" builtins.str"builtins.list
14+
Noner�
15+
aws_access_key_idPlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.aws_access_key_idh
16+
$Union[pydantic.types.SecretStr,None]4
17+
pydantic.types.SecretStr"pydantic.types.SecretStr
18+
Noner�
19+
aws_secret_access_keyTlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.aws_secret_access_keyh
20+
$Union[pydantic.types.SecretStr,None]4
21+
pydantic.types.SecretStr"pydantic.types.SecretStr
22+
Noner�
23+
aws_session_tokenPlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.aws_session_tokenh
24+
$Union[pydantic.types.SecretStr,None]4
25+
pydantic.types.SecretStr"pydantic.types.SecretStr
26+
Noner�
27+
base_model_idLlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.base_model_idD
28+
Union[builtins.str,None]
29+
builtins.str" builtins.str
30+
Noner�
31+
32+
base_modelIlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.base_modelD
33+
Union[builtins.str,None]
34+
builtins.str" builtins.str
35+
Nonerh
36+
bedrock_clientMlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.bedrock_client
37+
Anyr�
38+
cacheDlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.cacheT
39+
Union[Any,builtins.bool,None]
40+
Any
41+
builtins.bool"builtins.bool
42+
Noner�
43+
callback_managerOlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.callback_manager&
44+
Union[Any,None]
45+
Any
46+
Noner^
47+
callbacksHlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.callbacks
48+
AnyrX
49+
clientElangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.client
50+
AnyrX
51+
configElangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.config
52+
Anyr�
53+
credentials_profile_nameWlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.credentials_profile_nameD
54+
Union[builtins.str,None]
55+
builtins.str" builtins.str
56+
Noner�
57+
custom_get_token_idsSlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.custom_get_token_ids�
58+
+Union[CallableType[builtins.function],None]K
59+
CallableType[builtins.function]&
60+
builtins.function"builtins.function
61+
Noner�
62+
disable_streamingPlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.disable_streaming�
63+
*Union[builtins.bool,Literal[builtins.str]]
64+
builtins.bool"builtins.bool7
65+
Literal[builtins.str] 
66+
builtins.str" builtins.strr�
67+
endpoint_urlKlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.endpoint_urlD
68+
Union[builtins.str,None]
69+
builtins.str" builtins.str
70+
Noner�
71+
base_urlGlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.base_urlD
72+
Union[builtins.str,None]
73+
builtins.str" builtins.str
74+
Noner�
75+
guard_last_turn_onlySlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.guard_last_turn_only
76+
builtins.bool"builtins.boolr�
77+
guardrail_configOlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.guardrail_config�
78+
+Union[builtins.dict[builtins.str,Any],None]W
79+
builtins.dict[builtins.str,Any]
80+
builtins.str" builtins.str
81+
Any"builtins.dict
82+
Noner�
83+
84+
guardrailsIlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.guardrails�
85+
+Union[builtins.dict[builtins.str,Any],None]W
86+
builtins.dict[builtins.str,Any]
87+
builtins.str" builtins.str
88+
Any"builtins.dict
89+
Noner�
90+
91+
max_tokensIlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.max_tokensD
92+
Union[builtins.int,None]
93+
builtins.int" builtins.int
94+
Noner�
95+
metadataGlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.metadata�
96+
+Union[builtins.dict[builtins.str,Any],None]W
97+
builtins.dict[builtins.str,Any]
98+
builtins.str" builtins.str
99+
Any"builtins.dict
100+
Nonerq
101+
model_idGlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.model_id
102+
builtins.str" builtins.strrk
103+
modelDlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.model
104+
builtins.str" builtins.strr�
105+
performance_configQlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.performance_config�
106+
,Union[typing.Mapping[builtins.str,Any],None]Y
107+
typing.Mapping[builtins.str,Any]
108+
builtins.str" builtins.str
109+
Any"typing.Mapping
110+
Nonerq
111+
providerGlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.provider
112+
builtins.str" builtins.strr�
113+
rate_limiterKlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.rate_limiter&
114+
Union[Any,None]
115+
Any
116+
Noner�
117+
118+
raw_blocksIlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.raw_blocks�
119+
:Union[builtins.list[builtins.dict[builtins.str,Any]],None]�
120+
.builtins.list[builtins.dict[builtins.str,Any]]W
121+
builtins.dict[builtins.str,Any]
122+
builtins.str" builtins.str
123+
Any"builtins.dict"builtins.list
124+
Noner�
125+
region_nameJlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.region_nameD
126+
Union[builtins.str,None]
127+
builtins.str" builtins.str
128+
Noner�
129+
request_metadataOlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.request_metadata�
130+
4Union[builtins.dict[builtins.str,builtins.str],None]u
131+
(builtins.dict[builtins.str,builtins.str]
132+
builtins.str" builtins.str
133+
builtins.str" builtins.str"builtins.dict
134+
Noner�
135+
stop_sequencesMlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.stop_sequences�
136+
'Union[builtins.list[builtins.str],None]J
137+
builtins.list[builtins.str]
138+
builtins.str" builtins.str"builtins.list
139+
Noner�
140+
stopClangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.stop�
141+
'Union[builtins.list[builtins.str],None]J
142+
builtins.list[builtins.str]
143+
builtins.str" builtins.str"builtins.list
144+
Noner�
145+
supports_tool_choice_valuesZlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.supports_tool_choice_values�
146+
eUnion[typing.Sequence[Union[Literal[builtins.str],Literal[builtins.str],Literal[builtins.str]]],None]�
147+
Ytyping.Sequence[Union[Literal[builtins.str],Literal[builtins.str],Literal[builtins.str]]]�
148+
HUnion[Literal[builtins.str],Literal[builtins.str],Literal[builtins.str]]7
149+
Literal[builtins.str] 
150+
builtins.str" builtins.str7
151+
Literal[builtins.str] 
152+
builtins.str" builtins.str7
153+
Literal[builtins.str] 
154+
builtins.str" builtins.str"typing.Sequence
155+
Noner�
156+
tagsClangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.tags�
157+
'Union[builtins.list[builtins.str],None]J
158+
builtins.list[builtins.str]
159+
builtins.str" builtins.str"builtins.list
160+
Noner�
161+
temperatureJlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.temperatureJ
162+
Union[builtins.float,None]
163+
builtins.float"builtins.float
164+
Noner�
165+
top_pDlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.top_pJ
166+
Union[builtins.float,None]
167+
builtins.float"builtins.float
168+
Nonerq
169+
verboseFlangchain_aws.chat_models.bedrock_converse.ChatBedrockConverse.verbose
170+
builtins.bool"builtins.bool*�
171+
__annotations__:langchain_aws.chat_models.bedrock_converse.__annotations__W
172+
builtins.dict[builtins.str,Any]
173+
builtins.str" builtins.str
174+
Any"builtins.dict*J
175+
BaseCache4langchain_aws.chat_models.bedrock_converse.BaseCache
176+
Any*^
177+
BaseCallbackManager>langchain_aws.chat_models.bedrock_converse.BaseCallbackManager
178+
Any*J
179+
Callbacks4langchain_aws.chat_models.bedrock_converse.Callbacks
180+
Any*V
181+
BaseRateLimiter:langchain_aws.chat_models.bedrock_converse.BaseRateLimiter
182+
Any

python-frontend/src/main/resources/org/sonar/python/types/custom_protobuf/langchain_aws.chat_models.protobuf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
langchain_aws.chat_models*z
3+
__path__"langchain_aws.chat_models.__path__J
4+
builtins.list[builtins.str]
5+
builtins.str" builtins.str"builtins.list*�
6+
__annotations__)langchain_aws.chat_models.__annotations__W
7+
builtins.dict[builtins.str,Any]
8+
builtins.str" builtins.str
9+
Any"builtins.dict

0 commit comments

Comments
 (0)