1515except ModuleNotFoundError :
1616 pass
1717
18+ have_black = False
19+ try :
20+ import black
21+ have_black = True
22+ except ModuleNotFoundError :
23+ pass
24+
25+
26+ # noinspection PyBroadException
27+ def pretty_format_python (python_txt : str , * , black_mode = None ) -> str :
28+ """
29+ Format Python code, using black.
30+
31+ :param python_txt: Python code
32+ :param black_mode: options for black
33+ :return: formatted Python code
34+ """
35+ assert have_black
36+ assert isinstance (python_txt , str )
37+ formatted_python = python_txt .strip ('\n ' ) + '\n '
38+ if len (formatted_python .strip ()) > 0 :
39+ if black_mode is None :
40+ black_mode = black .FileMode ()
41+ try :
42+ formatted_python = black .format_str (formatted_python , mode = black_mode )
43+ formatted_python = formatted_python .strip ('\n ' ) + '\n '
44+ except Exception :
45+ pass
46+ return formatted_python
1847
1948
20- def convert_py_code_to_notebook (text : str ) -> nbformat .notebooknode .NotebookNode :
49+ def convert_py_code_to_notebook (
50+ text : str ,
51+ * ,
52+ use_black :bool = False ) -> nbformat .notebooknode .NotebookNode :
2153 """
2254 Convert python text to a notebook.
2355 "''' begin text" ends any open blocks, and starts a new markdown block (triple double quotes also allowed)
2456 "''' # end text" ends text, and starts a new code block (triple double quotes also allowed)
2557 "'''end code'''" ends code blocks, and starts a new code block (triple double quotes also allowed)
2658
2759 :param text: Python text to convert.
60+ :param use_black: if True use black to re-format Python code
2861 :return: a notebook
2962 """
3063 # https://stackoverflow.com/a/23729611/6901725
3164 # https://nbviewer.org/gist/fperez/9716279
3265 assert isinstance (text , str )
66+ assert isinstance (use_black , bool )
3367 lines = text .splitlines ()
3468 begin_text_regexp = re .compile (r"^\s*r?((''')|(\"\"\"))\s*begin\s+text\s*$" )
3569 end_text_regexp = re .compile (r"^\s*r?((''')|(\"\"\"))\s*#\s*end\s+text\s*$" )
@@ -55,9 +89,11 @@ def convert_py_code_to_notebook(text: str) -> nbformat.notebooknode.NotebookNode
5589 code_end = end_code_regexp .match (line )
5690 if is_end or text_start or code_start or code_end :
5791 if (collecting_python is not None ) and (len (collecting_python ) > 0 ):
58- txt_block = ('\n ' .join (collecting_python )).strip ('\n ' ) + '\n '
59- if len (txt_block .strip ()) > 0 :
60- cells .append (nbf_v .new_code_cell (txt_block ))
92+ python_block = ('\n ' .join (collecting_python )).strip ('\n ' ) + '\n '
93+ if len (python_block .strip ()) > 0 :
94+ if use_black and have_black :
95+ python_block = pretty_format_python (python_block )
96+ cells .append (nbf_v .new_code_cell (python_block ))
6197 if (collecting_text is not None ) and (len (collecting_text ) > 0 ):
6298 txt_block = ('\n ' .join (collecting_text )).strip ('\n ' ) + '\n '
6399 if len (txt_block .strip ()) > 0 :
@@ -96,7 +132,12 @@ def prepend_code_cell_to_notebook(
96132 return nb_out
97133
98134
99- def convert_py_file_to_notebook (* , py_file : str , ipynb_file : str ) -> None :
135+ def convert_py_file_to_notebook (
136+ py_file : str ,
137+ * ,
138+ ipynb_file : str ,
139+ use_black : bool = False ,
140+ ) -> None :
100141 """
101142 Convert python text to a notebook.
102143 "''' begin text" ends any open blocks, and starts a new markdown block (triple double quotes also allowed)
@@ -105,36 +146,47 @@ def convert_py_file_to_notebook(*, py_file: str, ipynb_file: str) -> None:
105146
106147 :param py_file: Path to python source file.
107148 :param ipynb_file: Path to notebook result file.
149+ :param use_black: if True use black to re-format Python code
108150 :return: nothing
109151 """
110152 assert isinstance (py_file , str )
111153 assert isinstance (ipynb_file , str )
154+ assert isinstance (use_black , bool )
112155 assert py_file != ipynb_file # prevent clobber
113156 with open (py_file , 'r' ) as f :
114157 text = f .read ()
115- nb = convert_py_code_to_notebook (text )
158+ nb = convert_py_code_to_notebook (text , use_black = use_black )
116159 with open (ipynb_file , 'w' ) as f :
117160 nbformat .write (nb , f )
118161
119162
120- def convert_notebook_code_to_py (nb : nbformat .notebooknode .NotebookNode ) -> str :
163+ def convert_notebook_code_to_py (
164+ nb : nbformat .notebooknode .NotebookNode ,
165+ * ,
166+ use_black : bool = False ,
167+ ) -> str :
121168 """
122169 Convert ipython notebook inputs to a py code.
123170 "''' begin text" ends any open blocks, and starts a new markdown block (triple double quotes also allowed)
124171 "''' # end text" ends text, and starts a new code block (triple double quotes also allowed)
125172 "'''end code'''" ends code blocks, and starts a new code block (triple double quotes also allowed)
126173
127174 :param nb: notebook
175+ :param use_black: if True use black to re-format Python code
128176 :return: Python source code
129177 """
178+ assert isinstance (use_black , bool )
130179 res = []
131180 code_needs_end = False
132181 for cell in nb .cells :
133182 if len (cell .source .strip ()) > 0 :
134183 if cell .cell_type == 'code' :
135184 if code_needs_end :
136185 res .append ('\n """end code"""\n ' )
137- res .append (cell .source .strip ('\n ' ))
186+ py_text = cell .source .strip ('\n ' ) + '\n '
187+ if use_black and have_black :
188+ py_text = pretty_format_python (py_text )
189+ res .append (py_text )
138190 code_needs_end = True
139191 else :
140192 res .append ('\n """ begin text' )
@@ -145,7 +197,12 @@ def convert_notebook_code_to_py(nb: nbformat.notebooknode.NotebookNode) -> str:
145197 return res_text
146198
147199
148- def convert_notebook_file_to_py (* , ipynb_file : str , py_file : str ) -> None :
200+ def convert_notebook_file_to_py (
201+ ipynb_file : str ,
202+ * ,
203+ py_file : str ,
204+ use_black : bool = False ,
205+ ) -> None :
149206 """
150207 Convert ipython notebook inputs to a py file.
151208 "''' begin text" ends any open blocks, and starts a new markdown block (triple double quotes also allowed)
@@ -154,14 +211,16 @@ def convert_notebook_file_to_py(*, ipynb_file: str, py_file: str) -> None:
154211
155212 :param ipynb_file: Path to notebook input file.
156213 :param py_file: Path to python result file.
214+ :param use_black: if True use black to re-format Python code
157215 :return: nothing
158216 """
159217 assert isinstance (py_file , str )
160218 assert isinstance (ipynb_file , str )
219+ assert isinstance (use_black , bool )
161220 assert py_file != ipynb_file # prevent clobber
162221 with open (ipynb_file , "rb" ) as f :
163222 nb = nbformat .read (f , as_version = 4 )
164- py_source = convert_notebook_code_to_py (nb )
223+ py_source = convert_notebook_code_to_py (nb , use_black = use_black )
165224 with open (py_file , 'w' ) as f :
166225 f .write (py_source )
167226
0 commit comments