@@ -0,0 +1,43 @@

class TestProperty(object):
def __init__(self, name = "Default"):
self._x = None
self.name = name

def get_name(self):
return self.__name


def set_name(self, value):
self.__name = value


def del_name(self):
del self.__name
name = property(get_name, set_name, del_name, "name's docstring")

@property
def x(self):
return self._x

@x.setter
def x(self, value):
self._x = value

@x.deleter
def x(self):
del self._x

def main():
"""
"""
testObj = TestProperty()
testObj.x = 10
val = testObj.x

testObj.name = "Pydev"
debugType = testObj.name
print('TEST SUCEEDED!')

if __name__ == '__main__':
main()
@@ -215,7 +215,55 @@ def WriteRunThread(self, threadId):
def WriteKillThread(self, threadId):
self.Write("104\t%s\t%s" % (self.NextSeq(), threadId,))

#=======================================================================================================================
# WriterThreadCase13
#======================================================================================================================
class WriterThreadCase13(AbstractWriterThread):

TEST_FILE = NormFile('_debugger_case13.py')

def run(self):
self.StartSocket()
self.WriteAddBreakpoint(35, 'main')
self.Write("124\t%s\t%s" % (self.NextSeq(), "true;false;false;true"))
self.WriteMakeInitialRun()
threadId, frameId, line = self.WaitForBreakpointHit('111', True)

self.WriteGetFrame(threadId, frameId)

self.WriteStepIn(threadId)
threadId, frameId, line = self.WaitForBreakpointHit('107', True)
# Should go inside setter method
assert line == 25, 'Expected return to be in line 25, was: %s' % line

self.WriteStepIn(threadId)
threadId, frameId, line = self.WaitForBreakpointHit('107', True)

self.WriteStepIn(threadId)
threadId, frameId, line = self.WaitForBreakpointHit('107', True)
# Should go inside getter method
assert line == 21, 'Expected return to be in line 21, was: %s' % line

self.WriteStepIn(threadId)
threadId, frameId, line = self.WaitForBreakpointHit('107', True)

# Disable property tracing
self.Write("124\t%s\t%s" % (self.NextSeq(), "true;true;true;true"))
self.WriteStepIn(threadId)
threadId, frameId, line = self.WaitForBreakpointHit('107', True)
# Should Skip step into properties setter
assert line == 39, 'Expected return to be in line 39, was: %s' % line

# Enable property tracing
self.Write("124\t%s\t%s" % (self.NextSeq(), "true;false;false;true"))
self.WriteStepIn(threadId)
threadId, frameId, line = self.WaitForBreakpointHit('107', True)
# Should go inside getter method
assert line == 8, 'Expected return to be in line 8, was: %s' % line

self.WriteRunThread(threadId)

self.finishedOk = True

#=======================================================================================================================
# WriterThreadCase12
@@ -741,6 +789,9 @@ def testCase11(self):

def testCase12(self):
self.CheckCase(WriterThreadCase12)

def testCase13(self):
self.CheckCase(WriterThreadCase13)


def testCase1a(self):
@@ -778,7 +829,9 @@ def testCase11a(self):

def testCase12a(self):
self.CheckCase(WriterThreadCase12, False)


def testCase13a(self):
self.CheckCase(WriterThreadCase13, False)

def GetLocationFromLine(line):
loc = line.split('=')[1].strip()
@@ -51,6 +51,7 @@
import org.python.pydev.debug.model.remote.RunCommand;
import org.python.pydev.debug.model.remote.SendPyExceptionCommand;
import org.python.pydev.debug.model.remote.SetBreakpointCommand;
import org.python.pydev.debug.model.remote.SetPropertyTraceCommand;
import org.python.pydev.debug.model.remote.ThreadListCommand;
import org.python.pydev.debug.model.remote.VersionCommand;
import org.python.pydev.debug.ui.launching.PythonRunnerConfig;
@@ -61,7 +62,7 @@
* @author Fabio
*/
@SuppressWarnings("restriction")
public abstract class AbstractDebugTarget extends AbstractDebugTargetWithTransmission implements IDebugTarget, ILaunchListener, IExceptionsBreakpointListener {
public abstract class AbstractDebugTarget extends AbstractDebugTargetWithTransmission implements IDebugTarget, ILaunchListener, IExceptionsBreakpointListener, IPropertyTraceListener {

private static final boolean DEBUG = false;

@@ -246,6 +247,16 @@ public void onSetConfiguredExceptions() {
this.postCommand(sendCmd);
}

/*
* (non-Javadoc)
* @see org.python.pydev.debug.model.IPropertyTraceListener#onSetPropertyTraceConfiguration()
*/
public void onSetPropertyTraceConfiguration() {
// Sending whether to trace python property
SetPropertyTraceCommand sendCmd = new SetPropertyTraceCommand(this);
this.postCommand(sendCmd);
}

/**
* @return true if the given breakpoint is supported by this target
*/
@@ -590,8 +601,9 @@ public void initialize() {
// now, register all the breakpoints in all projects
addBreakpointsFor(ResourcesPlugin.getWorkspace().getRoot());

// Sending python exceptions before sending run command
// Sending python exceptions and property trace state before sending run command
this.onSetConfiguredExceptions();
this.onSetPropertyTraceConfiguration();

// Send the run command, and we are off
RunCommand run = new RunCommand(this);
@@ -0,0 +1,13 @@
package org.python.pydev.debug.model;

/**
* @author hussain.bohra
*/
public interface IPropertyTraceListener {

/**
* Called when user disable/re-enable property tracing
*/
void onSetPropertyTraceConfiguration();

}
@@ -43,6 +43,7 @@ public PyDebugTarget(ILaunch launch, IProcess process, IPath[] file, RemoteDebug
IBreakpointManager breakpointManager= DebugPlugin.getDefault().getBreakpointManager();
breakpointManager.addBreakpointListener(this);
PyExceptionBreakPointManager.getInstance().addListener(this);
PyPropertyTraceManager.getInstance().addListener(this);
// we have to know when we get removed, so that we can shut off the debugger
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
}
@@ -53,6 +54,7 @@ public void launchRemoved(ILaunch launch) {
IBreakpointManager breakpointManager= DebugPlugin.getDefault().getBreakpointManager();
breakpointManager.removeBreakpointListener(this);
PyExceptionBreakPointManager.getInstance().removeListener(this);
PyPropertyTraceManager.getInstance().removeListener(this);
debugger.dispose();
debugger = null;
}
@@ -0,0 +1,67 @@
package org.python.pydev.debug.model;

import org.python.pydev.core.ListenerList;
import org.python.pydev.debug.core.ConfigureExceptionsFileUtils;

public class PyPropertyTraceManager {

// Static variables
public static final String PROPERTY_TRACE_STATE = "property_trace_state.prefs";

private static PyPropertyTraceManager pyPropertyTraceManager;

// For instance
private ListenerList<IPropertyTraceListener> listeners = new ListenerList<IPropertyTraceListener>(
IPropertyTraceListener.class);

/**
* Singleton: private constructor.
*/
private PyPropertyTraceManager() {

}

public static synchronized PyPropertyTraceManager getInstance() {
if (pyPropertyTraceManager == null) {
pyPropertyTraceManager = new PyPropertyTraceManager();
}
return pyPropertyTraceManager;
}

// Getters

public String getPyPropertyTraceState() {
return ConfigureExceptionsFileUtils
.readFromMetadataFile(PROPERTY_TRACE_STATE);
}

public void setPyPropertyTraceState(boolean replaceProperty,
boolean disableGetterTrace, boolean disableSetterTrace,
boolean disableDelterTrace) {

String propertyTrace = Boolean.toString(replaceProperty)
+ ConfigureExceptionsFileUtils.DELIMITER
+ Boolean.toString(disableGetterTrace)
+ ConfigureExceptionsFileUtils.DELIMITER
+ Boolean.toString(disableSetterTrace)
+ ConfigureExceptionsFileUtils.DELIMITER
+ Boolean.toString(disableDelterTrace);
ConfigureExceptionsFileUtils.writeToFile(
PyPropertyTraceManager.PROPERTY_TRACE_STATE, propertyTrace,
false);

for (IPropertyTraceListener listener : this.listeners.getListeners()) {
listener.onSetPropertyTraceConfiguration();
}
}

// Listeners

public void addListener(IPropertyTraceListener listener) {
this.listeners.add(listener);
}

public void removeListener(IPropertyTraceListener listener) {
this.listeners.remove(listener);
}
}
@@ -62,6 +62,7 @@ public abstract class AbstractDebuggerCommand {
static public final int CMD_SET_NEXT_STATEMENT = 121;
static public final int CMD_SET_PY_EXCEPTION = 122;
static public final int CMD_GET_FILE_CONTENTS = 123;
static public final int CMD_SET_PROPERTY_TRACE = 124;
static public final int CMD_ERROR = 901;
static public final int CMD_VERSION = 501;
static public final int CMD_RETURN = 502;
@@ -0,0 +1,20 @@
package org.python.pydev.debug.model.remote;

import org.python.pydev.debug.model.AbstractDebugTarget;
import org.python.pydev.debug.model.PyPropertyTraceManager;

public class SetPropertyTraceCommand extends AbstractDebuggerCommand {

public SetPropertyTraceCommand(AbstractDebugTarget debugger) {
super(debugger);
}

@Override
public String getOutgoing() {
PyPropertyTraceManager instance = PyPropertyTraceManager.getInstance();
String pyPropertyTraceState = instance.getPyPropertyTraceState().trim();
return makeCommand(AbstractDebuggerCommand.CMD_SET_PROPERTY_TRACE,
sequence, pyPropertyTraceState);
}

}
@@ -0,0 +1,153 @@
package org.python.pydev.debug.ui;

import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.SelectionDialog;
import org.python.pydev.debug.core.ConfigureExceptionsFileUtils;
import org.python.pydev.debug.model.PyPropertyTraceManager;

public class PyPropertyTraceDialog extends SelectionDialog {

// checkboxes to enable/disable stepping into properties
private Button disableStepIntoPropertiesCheck;
private Button disableStepIntoGetterCheck;
private Button disableStepIntoSetterCheck;
private Button disableStepIntoDeleterCheck;

// By default user can step into properties
private boolean disableStepIntoProperties = false;
private boolean disableStepIntoGetter = false;
private boolean disableStepIntoSetter = false;
private boolean disableStepIntoDeleter = false;

public PyPropertyTraceDialog(Shell parentShell) {
super(parentShell);
}

/**
* Adds the checkboxes to the dialog
*
* @param composite
*/
private void createStepIntoOptions(Composite composite) {

List<String> pyPropertyTraceStatesList = ConfigureExceptionsFileUtils
.getConfiguredExceptions(PyPropertyTraceManager.PROPERTY_TRACE_STATE);

if (pyPropertyTraceStatesList.size() == 4) {
disableStepIntoProperties = Boolean
.parseBoolean(pyPropertyTraceStatesList.get(0));
disableStepIntoGetter = Boolean
.parseBoolean(pyPropertyTraceStatesList.get(1));
disableStepIntoSetter = Boolean
.parseBoolean(pyPropertyTraceStatesList.get(2));
disableStepIntoDeleter = Boolean
.parseBoolean(pyPropertyTraceStatesList.get(3));
}

disableStepIntoPropertiesCheck = new Button(composite, SWT.CHECK);
disableStepIntoPropertiesCheck.setText("Disable step into properties");
disableStepIntoPropertiesCheck.setSelection(disableStepIntoProperties);
createSelectionListener();

GridData gridData = new GridData();
gridData.horizontalIndent = 25;
disableStepIntoGetterCheck = new Button(composite, SWT.CHECK);
disableStepIntoGetterCheck
.setText("Disable step into property getters");
disableStepIntoGetterCheck.setSelection(disableStepIntoGetter);
disableStepIntoGetterCheck.setEnabled(disableStepIntoPropertiesCheck
.getSelection());
disableStepIntoGetterCheck.setLayoutData(gridData);

gridData = new GridData();
gridData.horizontalIndent = 25;
disableStepIntoSetterCheck = new Button(composite, SWT.CHECK);
disableStepIntoSetterCheck
.setText("Disable step into property setters");
disableStepIntoSetterCheck.setSelection(disableStepIntoSetter);
disableStepIntoSetterCheck.setEnabled(disableStepIntoPropertiesCheck
.getSelection());
disableStepIntoSetterCheck.setLayoutData(gridData);

gridData = new GridData();
gridData.horizontalIndent = 25;
disableStepIntoDeleterCheck = new Button(composite, SWT.CHECK);
disableStepIntoDeleterCheck
.setText("Disable step into property deleters");
disableStepIntoDeleterCheck.setSelection(disableStepIntoDeleter);
disableStepIntoDeleterCheck.setEnabled(disableStepIntoPropertiesCheck
.getSelection());
disableStepIntoDeleterCheck.setLayoutData(gridData);
}

/**
* Creates a selection listener for disableStepIntoPropertiesCheck
*/
private void createSelectionListener() {
disableStepIntoPropertiesCheck
.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent arg0) {
disableStepIntoGetterCheck.setSelection(false);
disableStepIntoGetterCheck
.setEnabled(disableStepIntoPropertiesCheck
.getSelection());
disableStepIntoSetterCheck.setSelection(false);
disableStepIntoSetterCheck
.setEnabled(disableStepIntoPropertiesCheck
.getSelection());
disableStepIntoDeleterCheck.setSelection(false);
disableStepIntoDeleterCheck
.setEnabled(disableStepIntoPropertiesCheck
.getSelection());
}

public void widgetDefaultSelected(SelectionEvent arg0) {
}
});
}

@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
createStepIntoOptions(composite);
return composite;
}

@Override
protected void okPressed() {
this.disableStepIntoProperties = disableStepIntoPropertiesCheck
.getSelection();
this.disableStepIntoGetter = disableStepIntoGetterCheck.getSelection();
this.disableStepIntoSetter = disableStepIntoSetterCheck.getSelection();
this.disableStepIntoDeleter = disableStepIntoDeleterCheck
.getSelection();
super.okPressed();
}

// Getters

public boolean isDisableStepIntoProperties() {
return disableStepIntoProperties;
}

public boolean isDisableStepIntoGetter() {
return disableStepIntoGetter;
}

public boolean isDisableStepIntoSetter() {
return disableStepIntoSetter;
}

public boolean isDisableStepIntoDeleter() {
return disableStepIntoDeleter;
}
}
@@ -0,0 +1,31 @@
package org.python.pydev.debug.ui.actions;

import org.eclipse.jface.action.IAction;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.python.pydev.debug.model.PyPropertyTraceManager;
import org.python.pydev.debug.ui.PyPropertyTraceDialog;
import org.python.pydev.editor.actions.PyAction;

public class PyPropertyTraceAction extends PyAction implements
IWorkbenchWindowActionDelegate {

public void run(IAction arg0) {
PyPropertyTraceDialog dialog = new PyPropertyTraceDialog(
getShell());
dialog.setTitle("Enable/Disable Step Into properties");
if (dialog.open() == PyPropertyTraceDialog.OK) {
PyPropertyTraceManager.getInstance().setPyPropertyTraceState(
dialog.isDisableStepIntoProperties(),
dialog.isDisableStepIntoGetter(),
dialog.isDisableStepIntoSetter(),
dialog.isDisableStepIntoDeleter());
}
}

public void dispose() {
}

public void init(IWorkbenchWindow arg0) {
}
}