Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/python_minifier/ast_compare.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import python_minifier.ast_compat as ast

from python_minifier.util import is_ast_node


class CompareError(RuntimeError):
"""
Expand All @@ -18,7 +16,7 @@ def __repr__(self):

def namespace(self, node):
if hasattr(node, 'namespace'):
if is_ast_node(node.namespace, (ast.FunctionDef, ast.ClassDef, 'AsyncFunctionDef')):
if isinstance(node.namespace, (ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef)):
return self.namespace(node.namespace) + '.' + node.namespace.name
elif isinstance(node.namespace, ast.Module):
return ''
Expand Down
32 changes: 32 additions & 0 deletions src/python_minifier/ast_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,35 @@ def __new__(cls, *args, **kwargs):
class Ellipsis(Constant): # type: ignore[no-redef]
def __new__(cls, *args, **kwargs):
return Constant(value=literal_eval('...'), *args, **kwargs)


# Create a dummy class for missing AST nodes
for _node_type in [
'AnnAssign',
'AsyncFor',
'AsyncFunctionDef',
'AsyncFunctionDef',
'AsyncWith',
'Bytes',
'Constant',
'DictComp',
'Exec',
'ListComp',
'MatchAs',
'MatchMapping',
'MatchStar',
'NameConstant',
'NamedExpr',
'Nonlocal',
'ParamSpec',
'SetComp',
'Starred',
'TryStar',
'TypeVar',
'TypeVarTuple',
'YieldFrom',
'arg',
'withitem',
]:
if _node_type not in globals():
globals()[_node_type] = type(_node_type, (AST,), {})
10 changes: 5 additions & 5 deletions src/python_minifier/ast_printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import python_minifier.ast_compat as ast

from python_minifier.util import is_ast_node
from python_minifier.util import is_constant_node


INDENT = ' '
Expand Down Expand Up @@ -69,16 +69,16 @@ def is_literal(node, field):
if hasattr(ast, 'Constant') and isinstance(node, ast.Constant) and field == 'value':
return True

if is_ast_node(node, ast.Num) and field == 'n':
if is_constant_node(node, ast.Num) and field == 'n':
return True

if is_ast_node(node, ast.Str) and field == 's':
if is_constant_node(node, ast.Str) and field == 's':
return True

if is_ast_node(node, 'Bytes') and field == 's':
if is_constant_node(node, ast.Bytes) and field == 's':
return True

if is_ast_node(node, 'NameConstant') and field == 'value':
if is_constant_node(node, ast.NameConstant) and field == 'value':
return True

return False
Expand Down
18 changes: 9 additions & 9 deletions src/python_minifier/expression_printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import python_minifier.ast_compat as ast

from python_minifier.token_printer import Delimiter, TokenPrinter
from python_minifier.util import is_ast_node
from python_minifier.util import is_constant_node


class ExpressionPrinter(object):
Expand Down Expand Up @@ -69,7 +69,7 @@ def precedence(self, node):

# Python2 parses negative ints as an ast.Num with a negative value.
# Make sure the Num get the precedence of the USub operator in this case.
if sys.version_info < (3, 0) and is_ast_node(node, ast.Num):
if sys.version_info < (3, 0) and is_constant_node(node, ast.Num):
if str(node.n)[0] == '-':
return self.precedences['USub']

Expand Down Expand Up @@ -208,7 +208,7 @@ def visit_Starred(self, node):
def visit_UnaryOp(self, node):
self.visit(node.op)

if sys.version_info < (3, 0) and isinstance(node.op, ast.USub) and is_ast_node(node.operand, ast.Num):
if sys.version_info < (3, 0) and isinstance(node.op, ast.USub) and is_constant_node(node.operand, ast.Num):
# For: -(1), which is parsed as a UnaryOp(USub, Num(1)).
# Without this special case it would be printed as -1
# This is fine, but python 2 will then parse it at Num(-1) so the AST wouldn't round-trip.
Expand Down Expand Up @@ -428,7 +428,7 @@ def visit_Attribute(self, node):
value_precedence = self.precedence(node.value)
attr_precedence = self.precedence(node)

if (value_precedence != 0 and (attr_precedence > value_precedence)) or is_ast_node(node.value, ast.Num):
if (value_precedence != 0 and (attr_precedence > value_precedence)) or is_constant_node(node.value, ast.Num):
self.printer.delimiter('(')
self._expression(node.value)
self.printer.delimiter(')')
Expand Down Expand Up @@ -462,7 +462,7 @@ def visit_Subscript(self, node):
self.visit_Slice(node.slice)
elif isinstance(node.slice, ast.ExtSlice):
self.visit_ExtSlice(node.slice)
elif is_ast_node(node.slice, ast.Ellipsis):
elif is_constant_node(node.slice, ast.Ellipsis):
self.visit_Ellipsis(node)
elif sys.version_info >= (3, 9) and isinstance(node.slice, ast.Tuple):
self.visit_Tuple(node.slice)
Expand Down Expand Up @@ -649,27 +649,27 @@ def visit_Expression(self, node):
self._expression(node.body)

def _expression(self, expression):
if is_ast_node(expression, (ast.Yield, 'YieldFrom')):
if isinstance(expression, (ast.Yield, ast.YieldFrom)):
self.printer.delimiter('(')
self._yield_expr(expression)
self.printer.delimiter(')')
elif isinstance(expression, ast.Tuple) and len(expression.elts) > 0:
self.printer.delimiter('(')
self.visit_Tuple(expression)
self.printer.delimiter(')')
elif is_ast_node(expression, 'NamedExpr'):
elif isinstance(expression, ast.NamedExpr):
self.printer.delimiter('(')
self.visit_NamedExpr(expression)
self.printer.delimiter(')')
else:
self.visit(expression)

def _testlist(self, test):
if is_ast_node(test, (ast.Yield, 'YieldFrom')):
if isinstance(test, (ast.Yield, ast.YieldFrom)):
self.printer.delimiter('(')
self._yield_expr(test)
self.printer.delimiter(')')
elif is_ast_node(test, 'NamedExpr'):
elif isinstance(test, ast.NamedExpr):
self.printer.delimiter('(')
self.visit_NamedExpr(test)
self.printer.delimiter(')')
Expand Down
6 changes: 3 additions & 3 deletions src/python_minifier/f_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from python_minifier.expression_printer import ExpressionPrinter
from python_minifier.ministring import MiniString
from python_minifier.token_printer import TokenTypes
from python_minifier.util import is_ast_node
from python_minifier.util import is_constant_node


class FString(object):
Expand Down Expand Up @@ -70,7 +70,7 @@ def candidates(self):
nested_allowed.remove(quote)

for v in self.node.values:
if is_ast_node(v, ast.Str):
if is_constant_node(v, ast.Str):

# Could this be used as a debug specifier?
if len(candidates) < 10:
Expand Down Expand Up @@ -348,7 +348,7 @@ def candidates(self):

candidates = ['']
for v in self.node.values:
if is_ast_node(v, ast.Str):
if is_constant_node(v, ast.Str):
candidates = [x + self.str_for(v.s) for x in candidates]
elif isinstance(v, ast.FormattedValue):
candidates = [
Expand Down
19 changes: 9 additions & 10 deletions src/python_minifier/module_printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from .expression_printer import ExpressionPrinter
from .token_printer import Delimiter
from .util import is_ast_node


class ModulePrinter(ExpressionPrinter):
Expand Down Expand Up @@ -56,7 +55,7 @@ def visit_Exec(self, node):
def visit_Expr(self, node):
assert isinstance(node, ast.Expr)

if is_ast_node(node.value, (ast.Yield, 'YieldFrom')):
if isinstance(node.value, (ast.Yield, ast.YieldFrom)):
self._yield_expr(node.value)
else:
self._testlist(node.value)
Expand All @@ -83,7 +82,7 @@ def visit_Assign(self, node):
self.printer.delimiter('=')

# Yield nodes that are the sole node on the right hand side of an assignment do not need parens
if is_ast_node(node.value, (ast.Yield, 'YieldFrom')):
if isinstance(node.value, (ast.Yield, ast.YieldFrom)):
self._yield_expr(node.value)
else:
self._testlist(node.value)
Expand All @@ -98,7 +97,7 @@ def visit_AugAssign(self, node):
self.printer.delimiter('=')

# Yield nodes that are the sole node on the right hand side of an assignment do not need parens
if is_ast_node(node.value, (ast.Yield, 'YieldFrom')):
if isinstance(node.value, (ast.Yield, ast.YieldFrom)):
self._yield_expr(node.value)
else:
self._testlist(node.value)
Expand Down Expand Up @@ -144,7 +143,7 @@ def visit_Return(self, node):

self.printer.keyword('return')
if isinstance(node.value, ast.Tuple):
if sys.version_info < (3, 8) and [n for n in node.value.elts if is_ast_node(n, 'Starred')]:
if sys.version_info < (3, 8) and [n for n in node.value.elts if isinstance(n, ast.Starred)]:
self.printer.delimiter('(')
self._testlist(node.value)
self.printer.delimiter(')')
Expand Down Expand Up @@ -327,7 +326,7 @@ def visit_If(self, node, el=False):
self._suite(node.orelse)

def visit_For(self, node, is_async=False):
assert isinstance(node, ast.For) or (hasattr(ast, 'AsyncFor') and isinstance(node, ast.AsyncFor))
assert isinstance(node, (ast.For, ast.AsyncFor))

self.printer.newline()

Expand Down Expand Up @@ -363,7 +362,7 @@ def visit_While(self, node):
self._suite(node.orelse)

def visit_Try(self, node, star=False):
assert is_ast_node(node, (ast.Try, 'TryStar'))
assert isinstance(node, (ast.Try, ast.TryStar))

self.printer.newline()
self.printer.keyword('try')
Expand Down Expand Up @@ -441,7 +440,7 @@ def visit_ExceptHandler(self, node, star=False):
self._suite(node.body)

def visit_With(self, node, is_async=False):
assert is_ast_node(node, (ast.With, 'AsyncWith'))
assert isinstance(node, (ast.With, ast.AsyncWith))

self.printer.newline()

Expand Down Expand Up @@ -470,7 +469,7 @@ def visit_With(self, node, is_async=False):
self._suite(node.body)

def visit_withitem(self, node):
assert is_ast_node(node, ('withitem', ast.With))
assert isinstance(node, (ast.withitem, ast.With))

self._expression(node.context_expr)

Expand All @@ -479,7 +478,7 @@ def visit_withitem(self, node):
self._expression(node.optional_vars)

def visit_FunctionDef(self, node, is_async=False):
assert is_ast_node(node, (ast.FunctionDef, 'AsyncFunctionDef'))
assert isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))

self.printer.newline()

Expand Down
Loading