Skip to content

Commit e298c0d

Browse files
committed
Add transform to change return None into return
1 parent e569d48 commit e298c0d

File tree

7 files changed

+96
-4
lines changed

7 files changed

+96
-4
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def important(a):
2+
if not a:
3+
return None
4+
a.adjust(1)
5+
return a
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Remove Explicit Return None
2+
===========================
3+
4+
This transforms and ``return None`` statement into a ``return`` statement.
5+
A return statement with no value is equivalent to ``return None``.
6+
7+
The transform is always safe to use and enabled by default. Disable by passing the ``remove_explicit_return_none=False`` argument to the :func:`python_minifier.minify` function,
8+
or passing ``--no-remove-explicit-remove-none`` to the pyminify command.
9+
10+
Example
11+
-------
12+
13+
Input
14+
~~~~~
15+
16+
.. literalinclude:: remove_explicit_return_none.py
17+
18+
Output
19+
~~~~~~
20+
21+
.. literalinclude:: remove_explicit_return_none.min.py
22+
:language: python

src/python_minifier/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from python_minifier.transforms.remove_annotations import RemoveAnnotations
2424
from python_minifier.transforms.remove_asserts import RemoveAsserts
2525
from python_minifier.transforms.remove_debug import RemoveDebug
26+
from python_minifier.transforms.implicit_return_none import implicit_return_none
2627
from python_minifier.transforms.remove_literal_statements import RemoveLiteralStatements
2728
from python_minifier.transforms.remove_object_base import RemoveObject
2829
from python_minifier.transforms.remove_pass import RemovePass
@@ -64,7 +65,8 @@ def minify(
6465
convert_posargs_to_args=True,
6566
preserve_shebang=True,
6667
remove_asserts=False,
67-
remove_debug=False
68+
remove_debug=False,
69+
remove_explicit_return_none=True,
6870
):
6971
"""
7072
Minify a python module
@@ -94,6 +96,7 @@ def minify(
9496
:param bool preserve_shebang: Keep any shebang interpreter directive from the source in the minified output
9597
:param bool remove_asserts: If assert statements should be removed
9698
:param bool remove_debug: If conditional statements that test '__debug__ is True' should be removed
99+
:param bool remove_explicit_return_none: If explicit return None statements should be replaced with a bare return
97100
98101
:rtype: str
99102
@@ -127,6 +130,9 @@ def minify(
127130
if remove_debug:
128131
module = RemoveDebug()(module)
129132

133+
if remove_explicit_return_none:
134+
module = implicit_return_none(module)
135+
130136
bind_names(module)
131137
resolve_names(module)
132138

src/python_minifier/__init__.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ def minify(
2121
convert_posargs_to_args: bool = ...,
2222
preserve_shebang: bool = ...,
2323
remove_asserts: bool = ...,
24-
remove_debug: bool = ...
24+
remove_debug: bool = ...,
25+
remove_explicit_return_none: bool = ...
2526
) -> Text: ...
2627

2728
def unparse(module: ast.Module) -> Text: ...

src/python_minifier/__main__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,12 @@ def parse_args():
183183
help='Remove conditional statements that test __debug__ is True',
184184
dest='remove_debug',
185185
)
186-
186+
minification_options.add_argument(
187+
'--no-remove-explicit-return-none',
188+
action='store_false',
189+
help='Replace explicit return None with a bare return',
190+
dest='remove_explicit_return_none',
191+
)
187192
parser.add_argument('--version', '-v', action='version', version=version)
188193

189194
args = parser.parse_args()
@@ -248,7 +253,8 @@ def do_minify(source, filename, minification_args):
248253
convert_posargs_to_args=minification_args.convert_posargs_to_args,
249254
preserve_shebang=minification_args.preserve_shebang,
250255
remove_asserts=minification_args.remove_asserts,
251-
remove_debug=minification_args.remove_debug
256+
remove_debug=minification_args.remove_debug,
257+
remove_explicit_return_none=minification_args.remove_explicit_return_none,
252258
)
253259

254260

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import ast
2+
3+
from python_minifier.util import is_ast_node
4+
5+
6+
def implicit_return_none(node):
7+
8+
if isinstance(node, ast.Return) and is_ast_node(node.value, 'NameConstant') and node.value.value is None:
9+
# explicit return None
10+
node.value = None
11+
12+
for child in ast.iter_child_nodes(node):
13+
implicit_return_none(child)
14+
15+
return node
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import ast
2+
from python_minifier import unparse
3+
from python_minifier.ast_compare import compare_ast
4+
from python_minifier.transforms.implicit_return_none import implicit_return_none
5+
6+
7+
def remove_return_none(source):
8+
module = ast.parse(source, 'remove_return_none')
9+
10+
return implicit_return_none(module)
11+
12+
def test_remove_return_none():
13+
source = 'def a():return None'
14+
expected = 'def a():return'
15+
16+
expected_ast = ast.parse(expected)
17+
actual_ast = remove_return_none(source)
18+
compare_ast(expected_ast, actual_ast)
19+
20+
assert unparse(actual_ast) == expected
21+
22+
def test_implicit_return_none():
23+
source = 'def a():return'
24+
expected = source
25+
expected_ast = ast.parse(expected)
26+
actual_ast = remove_return_none(source)
27+
compare_ast(expected_ast, actual_ast)
28+
assert unparse(actual_ast) == expected
29+
30+
def test_return_value_unchanged():
31+
source = 'def a():return 0'
32+
expected = source
33+
expected_ast = ast.parse(expected)
34+
actual_ast = remove_return_none(source)
35+
compare_ast(expected_ast, actual_ast)
36+
assert unparse(actual_ast) == expected
37+

0 commit comments

Comments
 (0)