PY-77038 __repr__ value is truncated on copy

Merge-request: IJ-MR-157669
Merged-by: Egor Eliseev <Egor.Eliseev@jetbrains.com>
(cherry picked from commit 5b27f0dc362d8c023c8933dd22fe36b12c83e7e7)


Merge-request: IJ-MR-159313
Merged-by: Egor Eliseev <Egor.Eliseev@jetbrains.com>

GitOrigin-RevId: 4cdf4806ca54bb35fb42d977e1f43e7be82bbd43
This commit is contained in:
Egor Eliseev
2025-04-03 16:35:54 +00:00
committed by intellij-monorepo-bot
parent e5a76eabcf
commit 23780d7a8d
3 changed files with 89 additions and 24 deletions
@@ -112,15 +112,15 @@ if IS_PY3K:
def __init__(self, do_trim):
super(PydevdRepr, self).__init__()
self.fillvalue = '...'
self.maxdict = \
self.maxlist = \
self.maxtuple = \
self.maxset = \
self.maxfrozenset = \
self.maxdeque = \
self.maxarray = \
self.maxlong = \
self.maxstring = \
self.maxdict = MAX_REPR_ITEM_SIZE
self.maxlist = MAX_REPR_ITEM_SIZE
self.maxtuple = MAX_REPR_ITEM_SIZE
self.maxset = MAX_REPR_ITEM_SIZE
self.maxfrozenset = MAX_REPR_ITEM_SIZE
self.maxdeque = MAX_REPR_ITEM_SIZE
self.maxarray = MAX_REPR_ITEM_SIZE
self.maxlong = MAX_REPR_ITEM_SIZE
self.maxstring = MAX_REPR_ITEM_SIZE
self.maxother = MAX_REPR_ITEM_SIZE
self.do_trim = do_trim
@@ -160,8 +160,6 @@ if IS_PY3K:
else:
return "'{x}'".format(x=x)
def repr_dict(self, x, level):
n = len(x)
if n == 0: return '{}'
@@ -193,14 +191,20 @@ if IS_PY3K:
# if `__repr__` is overridden, then use `reprlib`
if x.__class__.__repr__ != object.__repr__:
return super().repr_instance(x, level)
if self.do_trim:
return super().repr_instance(x, level)
return repr(x)
# if `__str__` is overridden, then return str(x)
if x.__class__.__str__ != object.__str__:
return str(x)
# else use `reprlib`
return super().repr_instance(x, level)
if self.do_trim:
return super().repr_instance(x, level)
return '%s' % x
else:
def pydevd_repr_function(value, do_trim=True):
@@ -0,0 +1,39 @@
from dataclasses import dataclass
@dataclass
class Foo:
param0: str
param1: str
param2: str
param3: str
param4: str
param5: str
param6: str
param7: str
param8: str
param9: str
param10: str
param11: str
param12: str
param13: str
foo = Foo(
param0="param0 long value",
param1="param1 long value",
param2="param2 long value",
param3="param3 long value",
param4="param4 long value",
param5="param5 long value",
param6="param6 long value",
param7="param7 long value",
param8="param8 long value",
param9="param9 long value",
param10="param10 long value",
param11="param11 long value",
param12="param12 long value",
param13="param13 long value",
)
print(foo) # breakpoint
@@ -6,22 +6,14 @@ import com.jetbrains.env.debug.tasks.PyDebuggerTask
import com.jetbrains.python.debugger.PyDebuggerException
import com.jetbrains.python.debugger.QuotingPolicy
import com.jetbrains.python.debugger.getQuotingString
import com.jetbrains.python.psi.LanguageLevel
import org.junit.Assert
import org.junit.Test
class PythonDebuggerCopyActionTest : PyEnvTestCase() {
@Test
fun testGetFullValueFromCopyAction() {
runPythonTest(object : PyDebuggerTask("/debug", "test_get_full_value_from_copy_action.py") {
private val MINIMAL_LENGTH = 10000
@Throws(PyDebuggerException::class)
fun testLength(value: String?) {
// PyXCopyAction uses PyFullValueEvaluator, it uses myDebugProcess.evaluate
val result = myDebugProcess.evaluate(value, false, false)
Assert.assertTrue(result.value!!.length > MINIMAL_LENGTH)
}
runPythonTest(object : CopyValueTestCase("test_get_full_value_from_copy_action.py", 10000) {
override fun before() {
toggleBreakpoint(getFilePath(scriptName), 5)
}
@@ -35,6 +27,23 @@ class PythonDebuggerCopyActionTest : PyEnvTestCase() {
})
}
@Test
fun testGetFullValueFromCopyActionClass() {
runPythonTest(object : CopyValueTestCase("test_get_full_value_from_copy_action_class.py", 400) {
override fun before() {
toggleBreakpoint(getFilePath(scriptName), 38)
}
@Throws(Exception::class)
override fun testing() {
waitForPause()
testLength("foo")
resume()
}
})
}
@Test
fun testQuotingInCopyAction() {
runPythonTest(object : PyDebuggerTask("/debug", "test_quoting_value.py") {
@@ -69,4 +78,17 @@ class PythonDebuggerCopyActionTest : PyEnvTestCase() {
}
})
}
}
private open class CopyValueTestCase(scriptName: String, private val minLen: Int): PyDebuggerTask("/debug", scriptName) {
@Throws(PyDebuggerException::class)
fun testLength(value: String?) {
// PyXCopyAction uses PyFullValueEvaluator, it uses myDebugProcess.evaluate
val result = myDebugProcess.evaluate(value, false, false)
Assert.assertTrue(result.value!!.length > minLen)
}
override fun isLanguageLevelSupported(level: LanguageLevel): Boolean {
return level > LanguageLevel.PYTHON27
}
}