Skip to content

Commit 54fa576

Browse files
committed
Fix bugs with some classes and ordering
1 parent 291067e commit 54fa576

3 files changed

Lines changed: 27 additions & 15 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
# Changelog
22

33
## [Unreleased]
4-
### Added
5-
6-
### Changed
7-
84
### Fixed
5+
- Wrong hints behavior with some classes, related to the `__init__` inheritance logic
6+
- Wrong hint ordering when a positional argument is passed after keyword arguments
7+
- Messed up parameter ordering when unpacking is in the call expression
98

109
## [0.1.0] - 2022-07-15
11-
### Added
10+
### Added
1211
- Initial plugin release
1312

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pluginGroup = space.whitememory.pythoninlayparams
22
pluginName = Python Inlay Params
3-
pluginVersion = 0.1.0
3+
pluginVersion = 0.1.1
44

55
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
66
# for insight into build numbers and IntelliJ Platform versions.

src/main/kotlin/space/whitememory/pythoninlayparams/PythonInlayHintsProvider.kt

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ class PythonInlayHintsProvider : InlayParameterHintsProvider {
2626
return inlayInfos
2727
}
2828

29-
// Get the arguments of the call expression, excluding unpacking (*array and **dict)
30-
val args = element.arguments.filter { it !is PyStarArgument && it !is PyKeywordArgument }
31-
if (args.isEmpty()) {
29+
// Get the arguments of the call expression and quit if there are no arguments
30+
// or the only argument is unpacking (*list, **dict)
31+
val args = element.arguments
32+
if (args.isEmpty() || (args.size == 1 && args[0] is PyStarArgument)) {
3233
return inlayInfos
3334
}
3435

@@ -45,6 +46,7 @@ class PythonInlayHintsProvider : InlayParameterHintsProvider {
4546
}
4647

4748
val dataclassAttributes = mutableListOf<String>()
49+
var hasExplicitInit = false
4850
if (resolved is PyClass) {
4951
// This call is made by a class (initialization), so we want to find the parameters it takes.
5052
// In order to do so, we first have to check for an init method, and if not found,
@@ -56,16 +58,20 @@ class PythonInlayHintsProvider : InlayParameterHintsProvider {
5658
}
5759

5860
val evalContext = TypeEvalContext.codeAnalysis(element.project, element.containingFile)
59-
val initMethod = resolved.findMethodByName("__init__", true, evalContext)
60-
if (initMethod != null) {
61-
// Use the __init__ we found as the function to get parameters from
62-
resolved = initMethod
61+
val initMethod = resolved.findMethodByName("__init__", false, evalContext)
62+
resolved = if (initMethod != null) {
63+
// Take a note that this class has init
64+
hasExplicitInit = true
65+
initMethod
66+
} else {
67+
// Try to find init in its parent classes instead, otherwise stick to the attributes
68+
resolved.findMethodByName("__init__", true, evalContext) ?: resolved
6369
}
6470
}
6571

6672
val resolvedParameters = getElementFilteredParameters(resolved)
6773
// If there's no parameters in the object, we use the dataclass attributes instead, if there is any
68-
if (resolvedParameters.isEmpty() && dataclassAttributes.isNotEmpty()) {
74+
if (resolvedParameters.isEmpty() && dataclassAttributes.isNotEmpty() && !hasExplicitInit) {
6975
dataclassAttributes.zip(args).forEach {
7076
inlayInfos.add(InlayInfo(it.first, it.second.textOffset))
7177
}
@@ -81,9 +87,16 @@ class PythonInlayHintsProvider : InlayParameterHintsProvider {
8187
return inlayInfos
8288
}
8389

90+
// The argument is unpacking, we don't want to show hints any further
91+
// Because we can't be sure what parameters it covers
92+
if (arg is PyStarArgument) {
93+
return inlayInfos
94+
}
95+
8496
// Skip this parameter if its name starts with __,
8597
// or equals to the argument provided
86-
if (paramName != arg.name && !paramName.startsWith("__")) {
98+
if (arg !is PyKeywordArgument && paramName != arg.name && !paramName.startsWith("__")) {
99+
// TODO: Add more complex filters
87100
inlayInfos.add(InlayInfo(paramName, arg.textOffset))
88101
}
89102
}

0 commit comments

Comments
 (0)