Skip to content

Commit 65cd89d

Browse files
committed
Move PyCharm debug support into test framework
+ Move to using the PyCharm Diff & Merge tool for viewing sample mismatches
1 parent 7121f43 commit 65cd89d

File tree

12 files changed

+152
-121
lines changed

12 files changed

+152
-121
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,22 @@ This module is typically used in tests running under django.test.TestCase and re
135135

136136
#### Command line switches
137137

138-
We have added some custom functionality to pytest which can be enabled to launching pytest with the following switches:
138+
We have added some custom functionality to pytest which can be enabled by launching pytest with the following switches:
139139

140-
* `--sample-ask`: Enable a mode that invokes `kdiff3` to display diffs and, after user confirmation, can automatically update or write new test sample documents on mismatches.
140+
* `--sample-ask`: Enable a mode that display diffs and, after user confirmation, can automatically update or write new test sample documents on mismatches.
141141

142-
* `parameterize_dict`: Support for parameterizing test functions by adding a dict class member containing parameter sets.
143-
144-
* `--pycharm`: Attempt to move the cursor in PyCharm to the location of the test of failure.
142+
* `--pycharm`:
143+
144+
* Automatically open files where errors occur and move the cursor to the line of the error
145+
146+
* Show syntax highlighted diffs for scripts and data files using PyCharm's powerful diff viewer
147+
148+
* Also requires the path to the PyCharm binary to be configured in `DEBUG_PYCHARM_BIN_PATH` in `./conftest.py`.
145149

146150
* See `./conftest.py` for implementation and notes.
147151

152+
* `parameterize_dict`: Support for parameterizing test functions by adding a dict class member containing parameter sets.
153+
148154
Note: None of these switches can be used when running tests in parallel with xdist (`-n`, `--dist`, `--tx`).
149155

150156
#### Debugging tests with PyCharm

conftest.py

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
# limitations under the License.
2020
"""pytest setup and customization
2121
"""
22+
import d1_test.pycharm
2223
import logging
2324
import multiprocessing
2425
import os
@@ -52,9 +53,8 @@
5253
import django.db.transaction
5354
import django.db.utils
5455

55-
DEFAULT_DEBUG_PYCHARM_BIN_PATH = os.path.expanduser(
56-
'~/bin/JetBrains/pycharm.sh'
57-
)
56+
57+
5858
D1_SKIP_LIST = 'skip_passed/list'
5959
D1_SKIP_COUNT = 'skip_passed/count'
6060

@@ -260,30 +260,9 @@ def _print_skip_list():
260260

261261
def _open_error_in_pycharm(call):
262262
"""Attempt to open error locations in PyCharm. Use with --exitfirst (-x)"""
263-
# src_path, src_line, func_name = rep.location
264263
src_path = call.excinfo.traceback[-1].path
265264
src_line = call.excinfo.traceback[-1].lineno + 1
266-
logging.info('src_path="{}", src_line={}'.format(src_path, src_line))
267-
if src_path == '<string>':
268-
logging.debug('Unable to find location of error')
269-
return
270-
try:
271-
assert os.path.isfile(DEFAULT_DEBUG_PYCHARM_BIN_PATH), \
272-
'Path to PyCharm is incorrect'
273-
subprocess.call(
274-
[DEFAULT_DEBUG_PYCHARM_BIN_PATH, '--line', str(src_line), str(src_path)]
275-
)
276-
except subprocess.CalledProcessError as e:
277-
logging.warning(
278-
'Unable to open in PyCharm. error="{}" src_path="{}", src_line={}'.
279-
format(str(e), src_path, src_line)
280-
)
281-
else:
282-
logging.debug(
283-
'Opened in PyCharm. src_path="{}", src_line={}'.
284-
format(src_path, src_line)
285-
)
286-
265+
d1_test.pycharm.open_and_set_cursor(src_path, src_line)
287266

288267
# Fixtures
289268

dev_tools/src/d1_dev/trigger-pre-commit.py

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
there are more errors or S to skip directly to the next file.
3737
"""
3838

39+
import d1_test.pycharm
3940
import argparse
4041
import logging
4142
import os
@@ -49,9 +50,6 @@
4950
import d1_common.iter.dir
5051
import d1_common.util
5152

52-
# Path to PyCharm, for automatically moving to errors in the IDE
53-
DEFAULT_PYCHARM_BIN_PATH = os.path.expanduser('~/bin/JetBrains/pycharm.sh')
54-
5553

5654
def main():
5755
parser = argparse.ArgumentParser(
@@ -69,8 +67,7 @@ def main():
6967
'--ignore-invalid', action='store_true', help='Ignore invalid paths'
7068
)
7169
parser.add_argument(
72-
'--pycharm', action='store', default=DEFAULT_PYCHARM_BIN_PATH,
73-
help='Path to PyCharm binary. Set to "" to disable PyCharm integration'
70+
'--pycharm', action='store_true', help='Enable PyCharm integration'
7471
)
7572
parser.add_argument(
7673
'--debug', action='store_true', help='Debug level logging'
@@ -89,7 +86,7 @@ def main():
8986
trigger_path_list = sorted(
9087
set(specified_file_path_list).intersection(tracked_and_modified_path_list)
9188
)
92-
trigger_all_pre_commit_hooks(trigger_path_list)
89+
trigger_all_pre_commit_hooks(args, trigger_path_list)
9390

9491

9592
def get_specified_file_path_list(args):
@@ -108,16 +105,16 @@ def get_specified_file_path_list(args):
108105
return specified_file_path_list
109106

110107

111-
def trigger_all_pre_commit_hooks(trigger_path_list):
108+
def trigger_all_pre_commit_hooks(args, trigger_path_list):
112109
for trigger_path in trigger_path_list:
113110
logging.info('Checking file. path="{}"'.format(trigger_path))
114111
while True:
115-
recheck_bool = trigger_pre_commit_hook(trigger_path)
112+
recheck_bool = trigger_pre_commit_hook(args, trigger_path)
116113
if not recheck_bool:
117114
break
118115

119116

120-
def trigger_pre_commit_hook(trigger_path):
117+
def trigger_pre_commit_hook(args, trigger_path):
121118
try:
122119
res_str = subprocess.check_output(
123120
[
@@ -138,11 +135,11 @@ def trigger_pre_commit_hook(trigger_path):
138135
m = re.search(r'\.py:(\d+):', res_line)
139136
if m:
140137
logging.info('Error: {}'.format(res_line))
141-
if DEFAULT_PYCHARM_BIN_PATH is not None:
142-
open_exception_location_in_pycharm(trigger_path, m.group(1))
138+
if args.pycharm:
139+
d1_test.pycharm.open_and_set_cursor(trigger_path, m.group(1))
143140
while True:
144141
action_str = input(
145-
'Opened in PyCharm. Recheck: Enter, Skip file: s Enter: '
142+
'Recheck: Enter, Skip file: s Enter: '
146143
)
147144
if action_str == '':
148145
return True
@@ -168,23 +165,6 @@ def get_git_staged_files(repo):
168165
yield file_path
169166

170167

171-
def open_exception_location_in_pycharm(src_path, src_line_num):
172-
try:
173-
subprocess.call([
174-
DEFAULT_PYCHARM_BIN_PATH, '--line', src_line_num, src_path
175-
])
176-
except subprocess.CalledProcessError as e:
177-
logging.warning(
178-
'PyCharm debugging is enabled but opening the location of the exception '
179-
'in PyCharm failed. error="{}" src_path="{}", src_line={}'.format(
180-
str(e), src_path, src_line_num
181-
)
182-
)
183-
else:
184-
logging.debug(
185-
'Opened location of exception in PyCharm. src_path="{}", src_line={}'
186-
.format(src_path, src_line_num)
187-
)
188168

189169

190170
if __name__ == '__main__':

dev_tools/src/d1_dev/util.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import redbaron
3232
import redbaron.nodes
3333

34+
import d1_test.pycharm
3435

3536
def are_files_equal(old_file, new_file):
3637
with open(old_file, 'rb') as old_f:
@@ -94,7 +95,9 @@ def diff_update_file(module_path, module_str, show_diff=False, dry_run=False):
9495
if show_diff:
9596
try:
9697
tmp_file.seek(0)
97-
subprocess.check_call(['kdiff3', module_path, tmp_file.name])
98+
# subprocess.check_call(['kdiff3', module_path, tmp_file.name])
99+
d1_test.pycharm.diff(module_path, tmp_file.name)
100+
98101
# Running from the console
99102
# subprocess.check_call(['condiff.sh', module_path, tmp_file.name])
100103
except subprocess.CalledProcessError:

gmn/src/d1_gmn/app/gmn.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ def _warn_unsafe_for_prod(self):
128128
safe_settings_list = [
129129
('DEBUG', False),
130130
('DEBUG_GMN', False),
131-
('DEBUG_PYCHARM', False),
132131
('STAND_ALONE', False),
133132
('DATABASES.default.ATOMIC_REQUESTS', True),
134133
('SECRET_KEY', '<Do not modify this placeholder value>'),

gmn/src/d1_gmn/app/middleware/exception_handler.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ def _log_dataone_exception(self, e):
102102

103103
def _handle_internal_exception(self, request):
104104
self._log_internal_exception()
105-
if django.conf.settings.DEBUG_PYCHARM:
106-
self._open_exception_location_in_pycharm()
107105
if django.conf.settings.DEBUG:
108106
return self._django_html_exception_page()
109107
else:
@@ -157,37 +155,3 @@ def _traceback_to_trace_info(self):
157155
trace_info_list.append('Value: {}'.format(exc_value))
158156
return trace_info_list
159157

160-
# PyCharm debugging
161-
162-
def _open_exception_location_in_pycharm(self):
163-
src_path, src_line_num = self._get_project_location()
164-
try:
165-
subprocess.call([
166-
os.path.expanduser(django.conf.settings.DEBUG_PYCHARM_BIN_PATH),
167-
'--line', src_line_num, src_path
168-
])
169-
except subprocess.CalledProcessError as e:
170-
logging.warning(
171-
'PyCharm debugging is enabled but opening the location of the exception '
172-
'in PyCharm failed. error="{}" src_path="{}", src_line={}'.format(
173-
str(e), src_path, src_line_num
174-
)
175-
)
176-
else:
177-
logging.info(
178-
'Opened location of exception in PyCharm. src_path="{}", src_line={}'.
179-
format(src_path, src_line_num)
180-
)
181-
182-
def _get_project_location(self):
183-
"""Return the abs path and line number of the line of project code that was
184-
being executed when the exception was raised.
185-
"""
186-
exc_type, exc_value, exc_traceback = sys.exc_info()
187-
location_tup = ()
188-
while exc_traceback:
189-
co = exc_traceback.tb_frame.f_code
190-
if co.co_filename.startswith(django.conf.settings.BASE_DIR):
191-
location_tup = co.co_filename, str(exc_traceback.tb_lineno)
192-
exc_traceback = exc_traceback.tb_next
193-
return location_tup

gmn/src/d1_gmn/app/settings_default.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333

3434
DEBUG = False
3535
DEBUG_GMN = False
36-
DEBUG_PYCHARM = False
37-
DEBUG_PYCHARM_BIN = 'pycharm.sh'
3836
DEBUG_ECHO_REQUEST = False
3937
DEBUG_PROFILE_SQL = False
4038

gmn/src/d1_gmn/deployment/migrate_v1_to_v2.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ cp ${v1s} ${v2s}
3838
sed -ri "s/django.utils.log.NullHandler/logging.NullHandler/" ${v2s}
3939

4040
sed -ri "s/GMN_DEBUG/DEBUG_GMN/" ${v2s}
41-
sed -ri "/DEBUG_GMN\s*=/a\DEBUG_PYCHARM = False" ${v2s}
4241

4342
sed -ri "s/^(PUBLIC_OBJECT_LIST\s*=).*/\1 True/" ${v2s}
4443
sed -ri "s/^(PUBLIC_LOG_RECORDS\s*=).*/\1 True/" ${v2s}

gmn/src/d1_gmn/settings_template.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,6 @@
6363
# - Use for production.
6464
DEBUG_GMN = False
6565

66-
# Enable PyCharm debugging.
67-
# True:
68-
# - If GMN encounters an unhandled internal exception, GMN will attempt to move
69-
# the cursor in the PyCharm IDE to the code that was being executed when the
70-
# exception was raised. The exception is then handled as normal.
71-
# False (default):
72-
# - GMN handles exceptions as normal.
73-
DEBUG_PYCHARM = False
74-
75-
# Path to the PyCharm IDE binary.
76-
# - Only used if DEBUG_PYCHARM = True.
77-
# - If PyCharm is in the path, can typically left at 'pycharm.sh'
78-
# - If PyCharm is not in path, can be set to an absolute path. E.g.
79-
# '~/JetBrains/pycharm'
80-
DEBUG_PYCHARM_BIN = 'pycharm.sh'
81-
8266
# Enable request echo.
8367
# True:
8468
# - GMN will not process any requests. Instead, it will echo the requests

gmn/src/d1_gmn/settings_test.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636

3737
DEBUG = True
3838
DEBUG_GMN = True
39-
DEBUG_PYCHARM = False
40-
DEBUG_PYCHARM_BIN = 'pycharm.sh'
4139
DEBUG_ECHO_REQUEST = False
4240
DEBUG_PROFILE_SQL = False
4341

0 commit comments

Comments
 (0)