Python debugging in jupyter notebook - python-3.x

I am trying to understand debugging in jupyter notebooks. As per my understanding applying breakpoint() is the way to go about it but I am landing into a few issues that I describe below. I have a file named test_debugger.py in ./ that I am using as a prop in my little understanding endeavor.
#./test_debugger.py
def fun1(a):
print(a)
breakpoint()
if a > 3:
print(a+1)
breakpoint()
print(a+2)
breakpoint()
return None
Setup:
from test_debugger import *
Issues:
breakpoint() enters into debugging the interactive shell:
print(5)
breakpoint()
fun1(4)
breakpoint()
Running the above code gives me
5
--Return--
None
> <ipython-input-2-4276bdd18b42>(2)<module>()
1 print(5)
----> 2 breakpoint()
3 fun1(4)
4 breakpoint()
ipdb>
I press n and I want to jump to the next line in the cell but it gets into debugging the interactive shell I guess. Upon pressing nI get:
ipdb> n
[... skipped 1 hidden frame]
[... skipped 1 hidden frame]
[... skipped 1 hidden frame]
[... skipped 1 hidden frame]
> /home/nitin/miniconda/envs/nyraml386/lib/python3.8/site-packages/IPython/core/interactiveshell.py(3330)run_ast_nodes()
3328 to_run.append((node, 'single'))
3329
-> 3330 for node,mode in to_run:
3331 if mode == 'exec':
3332 mod = Module([node], [])
ipdb>
Question: How do I get the desired functionality of n (jump to next line in code written by me while remaining in the same function score) and s (jump to the next line in code written by me while switching the function scope wherever necessary).
PYTHONBREAKPOINT not available in jupyter notebook
The behavior expected: I have read that in case I want to disable all breakpoint() then I can set the env variable PYTHONBREAKPOINT to manage the behavior of breakpoint(). Specifically, I can set PYTHONBREAKPOINT=0 to disable breakpoint()
The behavior seen: PYTHONBREAKPOINT is not a variable available at all in jupyter notebook. Even if I set it equal to 0 that does not alter the disable breakpoint(). It is as if nothing happened
Question: How to manage breakpoint() when operating in jupyter notebooks. What is the way to bring in PYTHONBREAKPOINT into the notebook

Related

Issues using tkdraw.basic on jupyter VCS

So i tried to execute a code using the the tkdraw.basic library in jupyter notebook, and this is what i got :
Its just a simple program that is supposed to draw a line along the window :
import tkdraw.basic as graph
def ligne_horiz(y,larg):
for x in range(larg):
graph.plot(y,x)
graph.open_win(120,160)
ligne_horiz(50,160)
graph.wait()
hers the error :
AssertionError Traceback (most recent call last)
Cell In [12], line 7
4 for x in range(larg):
5 graph.plot(y,x)
----> 7 graph.open_win(120,160)
8 ligne_horiz(50,160)
9 graph.wait()
File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/tkdraw/basic.py:63, in open_win(height, width, zoom)
59 # pylint: disable=global-statement
60 # I really want to use a global in this module, to make those functions
61 # easier to use.
62 global _WINDOW
---> 63 assert not _WINDOW, "ERROR: function open() was called twice!"
64 _WINDOW = tkd.Screen((height, width), zoom, grid=False)
AssertionError: ERROR: function open() was called twice!
The code work perfectly on the terminal or in an another .py folder so i think the issue come from the Extension,
I tried to find any similar issue or an update in the library but nothing wrong apparently.(maybe a parameter in the extension it self ?)

SED style Multi address in Python?

I have an app that parses multiple Cisco show tech files. These files contain the output of multiple router commands in a structured way, let me show you an snippet of a show tech output:
`show clock`
20:20:50.771 UTC Wed Sep 07 2022
Time source is NTP
`show callhome`
callhome disabled
Callhome Information:
<SNIPET>
`show module`
Mod Ports Module-Type Model Status
--- ----- ------------------------------------- --------------------- ---------
1 52 16x10G + 32x10/25G + 4x100G Module N9K-X96136YC-R ok
2 52 16x10G + 32x10/25G + 4x100G Module N9K-X96136YC-R ok
3 52 16x10G + 32x10/25G + 4x100G Module N9K-X96136YC-R ok
4 52 16x10G + 32x10/25G + 4x100G Module N9K-X96136YC-R ok
21 0 Fabric Module N9K-C9504-FM-R ok
22 0 Fabric Module N9K-C9504-FM-R ok
23 0 Fabric Module N9K-C9504-FM-R ok
<SNIPET>
My app currently uses both SED and Python scripts to parse these files. I use SED to parse the show tech file looking for a specific command output, once I find it, I stop SED. This way I don't need to read all the file (these can get to be very big files). This is a snipet of my SED script:
sed -E -n '/`show running-config`|`show running`|`show running config`/{
p
:loop
n
p
/`show/q
b loop
}' $1/$file
As you can see I am using a multi address range in SED. My question specifically is, how can I achieve something similar in python? I have tried multiple combinations of flags: DOTALL and MULTILINE but I can't get the result I'm expecting, for example, I can get a match for the command I'm looking for, but python regex wont stop until the end of the file after the first match.
I am looking for something like this
sed -n '/`show clock`/,/`show/p'
I would like the regex match to stop parsing the file and print the results, immediately after seeing `show again , hope that makes sense and thank you all for reading me and for your help
You can use nested loops.
import re
def process_file(filename):
with open(filename) as f:
for line in f:
if re.search(r'`show running-config`|`show running`|`show running config`', line):
print(line)
for line1 in f:
print(line1)
if re.search(r'`show', line1):
return
The inner for loop will start from the next line after the one processed by the outer loop.
You can also do it with a single loop using a flag variable.
import re
def process_file(filename):
in_show = False
with open(filename) as f:
for line in f:
if re.search(r'`show running-config`|`show running`|`show running config`', line):
in_show = True
if in_show
print(line)
if re.search(r'`show', line1):
return

I am not able to call one python script from another script using os.system in Pycharm

My sample file in one project is:
import os
feature_name = 'neelam'
combo_boxes = {"'Primary CAN InterfaceComboBox": ["[CanSim, CanSim]", "best_match"],
"'Secondary CAN InterfaceComboBox": ["[CanSim, CanSim]", "best_match"],
"Seed Data SimulationComboBox": ["[Off, OFF]", "best_match"],
"Planter TypeComboBox": ["[_2160_FFT_24R30, 2160 Front Fold 24 Row 30 Inch]", "best_match"],
"BrandComboBox": ["[CaseIH, Case IH]", "best_match"],
"LATAM Gran Fertilizer InstalledComboBox": ["[Hydraulic, Hydraulic]", "best_match"],
"DiagnosticsComboBox": ["[On, ON]", "best_match"]}
for i in combo_boxes:
log_msg = 'Click on combo box {0} at {1}'.format(i, combo_boxes[i][0].split(",")[1][:-1])
print(log_msg)
Now I am trying to run sample file from another python script as given:
import os
script_string = r'C:\Neelam\Neelam_Dev\test_automation\FeatureTestScripts\Common\sample.py'
os.system(script_string)
But after running the second file, it is not printing the output of sample.py. It is just opening that file in Pycharm.

Console Screen Buffer Info shows incorrect X position

I recently found a great short code Why the irrelevant code made a difference? for obtaining console screen buffer info (which I include below) that replaces the huge code accompanying the standard 'CONSOLE_SCREEN_BUFFER_INFO()' method (which I won't include here!)
import ctypes
import struct
print("xxx",end="") # I added this to show what the problem is
hstd = ctypes.windll.kernel32.GetStdHandle(-11) # STD_OUTPUT_HANDLE = -11
csbi = ctypes.create_string_buffer(22)
res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(hstd, csbi)
width, height, curx, cury, wattr, left, top, right, bottom, maxx, maxy = struct.unpack("hhhhHhhhhhh", csbi.raw)
# The following two lines are also added
print() # To bring the cursor to next line for displaying infp
print(width, height, curx, cury, wattr, left, top, right, bottom, maxx, maxy) # Display what we got
Output:
80 250 0 7 7 0 0 79 24 80 43
This output is for Windows 10 MSDOS, with clearing the screen before running the code. However. 'curx' = 0 although it should be 3 (after printing "xxx"). The same phenomenon happens also with the 'CONSOLE_SCREEN_BUFFER_INFO()' method. Any idea what is the problem?
Also, any suggestion for a method of obtaining current cursor position -- besides 'curses' library -- will be welcome!
You need to flush the print buffer if you don't output a linefeed:
print("xxx",end="",flush=True)
Then I get the correct curx=3 with your code:
xxx
130 9999 3 0 14 0 0 129 75 130 76
BTW the original answer in the posted question is the "great" code. The "bitness" of HANDLE can break your code, and not defining .argtypes as a "shortcut" is usually the cause of most ctypes problems.

How to profile a vim plugin written in python

Vim offers the :profile command, which is really handy. But it is limited to Vim script -- when it comes to plugins implemented in python it isn't that helpful.
Currently I'm trying to understand what is causing a large delay on Denite. As it doesn't happen in vanilla Vim, but only on some specific conditions which I'm not sure how to reproduce, I couldn't find which setting/plugin is interfering.
So I turned to profiling, and this is what I got from :profile:
FUNCTION denite#vim#_start()
Defined: ~/.vim/bundle/denite.nvim/autoload/denite/vim.vim line 33
Called 1 time
Total time: 5.343388
Self time: 4.571928
count total (s) self (s)
1 0.000006 python3 << EOF
def _temporary_scope():
nvim = denite.rplugin.Neovim(vim)
try:
buffer_name = nvim.eval('a:context')['buffer_name']
if nvim.eval('a:context')['buffer_name'] not in denite__uis:
denite__uis[buffer_name] = denite.ui.default.Default(nvim)
denite__uis[buffer_name].start(
denite.rplugin.reform_bytes(nvim.eval('a:sources')),
denite.rplugin.reform_bytes(nvim.eval('a:context')),
)
except Exception as e:
import traceback
for line in traceback.format_exc().splitlines():
denite.util.error(nvim, line)
denite.util.error(nvim, 'Please execute :messages command.')
_temporary_scope()
if _temporary_scope in dir():
del _temporary_scope
EOF
1 0.000017 return []
(...)
FUNCTIONS SORTED ON TOTAL TIME
count total (s) self (s) function
1 5.446612 0.010563 denite#helper#call_denite()
1 5.396337 0.000189 denite#start()
1 5.396148 0.000195 <SNR>237_start()
1 5.343388 4.571928 denite#vim#_start()
(...)
I tried to use the python profiler directly by wrapping the main line:
import cProfile
cProfile.run(_temporary_scope(), '/path/to/log/file')
, but no luck -- just a bunch of errors from cProfile. Perhaps it is because the way python is started from Vim, as it is hinted here that it only works on the main thread.
I guess there should be an easier way of doing this.
The python profiler does work by enclosing the whole code,
cProfile.run("""
(...)
""", '/path/to/log/file')
, but it is not that helpful. Maybe it is all that is possible.

Resources