python-minifier 2.11.3__py2-none-any.whl → 3.0.0__py2-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_minifier/__init__.py +2 -1
- python_minifier/__init__.pyi +3 -3
- python_minifier/__main__.py +67 -8
- python_minifier/ast_compare.py +11 -11
- python_minifier/f_string.py +31 -31
- python_minifier/module_printer.py +6 -2
- python_minifier/token_printer.py +9 -1
- {python_minifier-2.11.3.dist-info → python_minifier-3.0.0.dist-info}/METADATA +2 -2
- {python_minifier-2.11.3.dist-info → python_minifier-3.0.0.dist-info}/RECORD +14 -14
- {python_minifier-2.11.3.dist-info → python_minifier-3.0.0.dist-info}/LICENSE +0 -0
- {python_minifier-2.11.3.dist-info → python_minifier-3.0.0.dist-info}/WHEEL +0 -0
- {python_minifier-2.11.3.dist-info → python_minifier-3.0.0.dist-info}/entry_points.txt +0 -0
- {python_minifier-2.11.3.dist-info → python_minifier-3.0.0.dist-info}/top_level.txt +0 -0
- {python_minifier-2.11.3.dist-info → python_minifier-3.0.0.dist-info}/zip-safe +0 -0
python_minifier/__init__.py
CHANGED
|
@@ -86,7 +86,8 @@ def minify(
|
|
|
86
86
|
:param str source: The python module source code
|
|
87
87
|
:param str filename: The original source filename if known
|
|
88
88
|
|
|
89
|
-
:param remove_annotations: Configures the removal of type annotations. True removes all annotations, False removes none.
|
|
89
|
+
:param remove_annotations: Configures the removal of type annotations. True removes all annotations, False removes none.
|
|
90
|
+
RemoveAnnotationsOptions can be used to configure the removal of specific annotations.
|
|
90
91
|
:type remove_annotations: bool or RemoveAnnotationsOptions
|
|
91
92
|
:param bool remove_pass: If Pass statements should be removed where possible
|
|
92
93
|
:param bool remove_literal_statements: If statements consisting of a single literal should be removed, including docstrings
|
python_minifier/__init__.pyi
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ast
|
|
2
2
|
|
|
3
|
-
from typing import Any,
|
|
3
|
+
from typing import Any, List, Optional, Text, Union
|
|
4
4
|
|
|
5
5
|
from .transforms.remove_annotations_options import RemoveAnnotationsOptions as RemoveAnnotationsOptions
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ class UnstableMinification(RuntimeError):
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def minify(
|
|
13
|
-
source:
|
|
13
|
+
source: Union[str, bytes],
|
|
14
14
|
filename: Optional[str] = ...,
|
|
15
15
|
remove_annotations: Union[bool, RemoveAnnotationsOptions] = ...,
|
|
16
16
|
remove_pass: bool = ...,
|
|
@@ -36,7 +36,7 @@ def unparse(module: ast.Module) -> Text: ...
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def awslambda(
|
|
39
|
-
source:
|
|
39
|
+
source: Union[str, bytes],
|
|
40
40
|
filename: Optional[Text] = ...,
|
|
41
41
|
entrypoint: Optional[Text] = ...
|
|
42
42
|
) -> Text: ...
|
python_minifier/__main__.py
CHANGED
|
@@ -8,6 +8,18 @@ from python_minifier import minify
|
|
|
8
8
|
from python_minifier.transforms.remove_annotations_options import RemoveAnnotationsOptions
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
class MinificationNotBeneficialError(Exception):
|
|
12
|
+
"""Raised when minification results in larger output than the original."""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
def stdout_write_bytes(data):
|
|
16
|
+
"""Write bytes to stdout with proper Python 2.7/3.x compatibility."""
|
|
17
|
+
if sys.version_info >= (3, 0):
|
|
18
|
+
sys.stdout.buffer.write(data)
|
|
19
|
+
else:
|
|
20
|
+
sys.stdout.write(data)
|
|
21
|
+
|
|
22
|
+
|
|
11
23
|
if sys.version_info >= (3, 8):
|
|
12
24
|
from importlib import metadata
|
|
13
25
|
|
|
@@ -51,12 +63,23 @@ examples:
|
|
|
51
63
|
if len(args.path) == 1 and args.path[0] == '-':
|
|
52
64
|
# minify stdin
|
|
53
65
|
source = sys.stdin.buffer.read() if sys.version_info >= (3, 0) else sys.stdin.read()
|
|
54
|
-
|
|
66
|
+
try:
|
|
67
|
+
minified = do_minify(source, 'stdin', args)
|
|
68
|
+
except MinificationNotBeneficialError:
|
|
69
|
+
# Use original source when minification isn't beneficial
|
|
70
|
+
if args.output:
|
|
71
|
+
with open(args.output, 'wb') as f:
|
|
72
|
+
f.write(source)
|
|
73
|
+
else:
|
|
74
|
+
# Write original source to stdout
|
|
75
|
+
stdout_write_bytes(source)
|
|
76
|
+
return
|
|
77
|
+
|
|
55
78
|
if args.output:
|
|
56
|
-
with open(args.output, '
|
|
79
|
+
with open(args.output, 'wb') as f:
|
|
57
80
|
f.write(minified)
|
|
58
81
|
else:
|
|
59
|
-
|
|
82
|
+
stdout_write_bytes(minified)
|
|
60
83
|
|
|
61
84
|
else:
|
|
62
85
|
# minify source paths
|
|
@@ -67,16 +90,30 @@ examples:
|
|
|
67
90
|
with open(path, 'rb') as f:
|
|
68
91
|
source = f.read()
|
|
69
92
|
|
|
70
|
-
|
|
93
|
+
try:
|
|
94
|
+
minified = do_minify(source, path, args)
|
|
95
|
+
except MinificationNotBeneficialError:
|
|
96
|
+
# Use original source when minification isn't beneficial
|
|
97
|
+
if args.in_place:
|
|
98
|
+
# File is already the original, no need to write
|
|
99
|
+
pass
|
|
100
|
+
elif args.output:
|
|
101
|
+
# Write original source to output
|
|
102
|
+
with open(args.output, 'wb') as f:
|
|
103
|
+
f.write(source)
|
|
104
|
+
else:
|
|
105
|
+
# Write original source to stdout
|
|
106
|
+
stdout_write_bytes(source)
|
|
107
|
+
continue
|
|
71
108
|
|
|
72
109
|
if args.in_place:
|
|
73
|
-
with open(path, '
|
|
110
|
+
with open(path, 'wb') as f:
|
|
74
111
|
f.write(minified)
|
|
75
112
|
elif args.output:
|
|
76
|
-
with open(args.output, '
|
|
113
|
+
with open(args.output, 'wb') as f:
|
|
77
114
|
f.write(minified)
|
|
78
115
|
else:
|
|
79
|
-
|
|
116
|
+
stdout_write_bytes(minified)
|
|
80
117
|
|
|
81
118
|
|
|
82
119
|
def parse_args():
|
|
@@ -280,6 +317,15 @@ def source_modules(args):
|
|
|
280
317
|
|
|
281
318
|
|
|
282
319
|
def do_minify(source, filename, minification_args):
|
|
320
|
+
"""Minify Python source code with size-based fallback.
|
|
321
|
+
|
|
322
|
+
:param bytes source: Source code as bytes (from file 'rb' or stdin.buffer)
|
|
323
|
+
:param str filename: Filename for error reporting
|
|
324
|
+
:param argparse.Namespace minification_args: CLI arguments for minification options
|
|
325
|
+
:returns: Minified source code as UTF-8 bytes
|
|
326
|
+
:rtype: bytes
|
|
327
|
+
:raises MinificationNotBeneficialError: When minified output is larger than original
|
|
328
|
+
"""
|
|
283
329
|
|
|
284
330
|
preserve_globals = []
|
|
285
331
|
if minification_args.preserve_globals:
|
|
@@ -308,7 +354,7 @@ def do_minify(source, filename, minification_args):
|
|
|
308
354
|
remove_class_attribute_annotations=minification_args.remove_class_attribute_annotations,
|
|
309
355
|
)
|
|
310
356
|
|
|
311
|
-
|
|
357
|
+
minified_result = minify(
|
|
312
358
|
source,
|
|
313
359
|
filename=filename,
|
|
314
360
|
combine_imports=minification_args.combine_imports,
|
|
@@ -330,6 +376,19 @@ def do_minify(source, filename, minification_args):
|
|
|
330
376
|
constant_folding=minification_args.constant_folding
|
|
331
377
|
)
|
|
332
378
|
|
|
379
|
+
# Encode minified result to bytes for comparison and output
|
|
380
|
+
minified_bytes = minified_result.encode('utf-8')
|
|
381
|
+
|
|
382
|
+
# Check if environment variable forces minified output
|
|
383
|
+
if os.environ.get('PYMINIFY_FORCE_BEST_EFFORT'):
|
|
384
|
+
return minified_bytes
|
|
385
|
+
|
|
386
|
+
# Compare byte lengths for accurate size comparison
|
|
387
|
+
if len(minified_bytes) > len(source):
|
|
388
|
+
raise MinificationNotBeneficialError("Minified output is longer than original")
|
|
389
|
+
|
|
390
|
+
return minified_bytes
|
|
391
|
+
|
|
333
392
|
|
|
334
393
|
if __name__ == '__main__':
|
|
335
394
|
main()
|
python_minifier/ast_compare.py
CHANGED
|
@@ -77,26 +77,26 @@ def compare_ast(l_ast, r_ast):
|
|
|
77
77
|
% (type(l_ast), field, len(l_list), type(r_ast), field, len(r_list)),
|
|
78
78
|
)
|
|
79
79
|
|
|
80
|
-
for i,
|
|
81
|
-
if isinstance(
|
|
82
|
-
compare_ast(
|
|
83
|
-
elif
|
|
80
|
+
for i, left, right in zip(counter(), l_list, r_list):
|
|
81
|
+
if isinstance(left, ast.AST) or isinstance(right, ast.AST):
|
|
82
|
+
compare_ast(left, right)
|
|
83
|
+
elif left != right:
|
|
84
84
|
raise CompareError(
|
|
85
85
|
l_ast,
|
|
86
86
|
r_ast,
|
|
87
87
|
'Fields do not match! %s.%s[%i]=%r, %s.%s[%i]=%r'
|
|
88
|
-
% (type(l_ast), field, i,
|
|
88
|
+
% (type(l_ast), field, i, left, type(r_ast), field, i, right),
|
|
89
89
|
)
|
|
90
90
|
|
|
91
91
|
else:
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
left_field = getattr(l_ast, field, None)
|
|
93
|
+
right_field = getattr(r_ast, field, None)
|
|
94
94
|
|
|
95
|
-
if isinstance(
|
|
96
|
-
compare_ast(
|
|
97
|
-
elif
|
|
95
|
+
if isinstance(left_field, ast.AST) or isinstance(right_field, ast.AST):
|
|
96
|
+
compare_ast(left_field, right_field)
|
|
97
|
+
elif left_field != right_field:
|
|
98
98
|
raise CompareError(
|
|
99
99
|
l_ast,
|
|
100
100
|
r_ast,
|
|
101
|
-
'Fields do not match! %s.%s=%r, %s.%s=%r' % (type(l_ast), field,
|
|
101
|
+
'Fields do not match! %s.%s=%r, %s.%s=%r' % (type(l_ast), field, left_field, type(r_ast), field, right_field),
|
|
102
102
|
)
|
python_minifier/f_string.py
CHANGED
|
@@ -272,31 +272,31 @@ class Str(object):
|
|
|
272
272
|
raise ValueError("Couldn't find a quote")
|
|
273
273
|
|
|
274
274
|
def _literals(self):
|
|
275
|
-
|
|
275
|
+
literal = ''
|
|
276
276
|
for c in self._s:
|
|
277
277
|
if not self._can_quote(c):
|
|
278
|
-
if
|
|
279
|
-
|
|
280
|
-
yield
|
|
281
|
-
|
|
278
|
+
if literal:
|
|
279
|
+
literal += self.current_quote
|
|
280
|
+
yield literal
|
|
281
|
+
literal = ''
|
|
282
282
|
|
|
283
283
|
self.current_quote = self._get_quote(c)
|
|
284
284
|
|
|
285
|
-
if
|
|
286
|
-
|
|
285
|
+
if literal == '':
|
|
286
|
+
literal += self.current_quote
|
|
287
287
|
|
|
288
288
|
if c == '\n':
|
|
289
|
-
|
|
289
|
+
literal += '\\n'
|
|
290
290
|
elif c == '\r':
|
|
291
|
-
|
|
291
|
+
literal += '\\r'
|
|
292
292
|
elif c == '\\':
|
|
293
|
-
|
|
293
|
+
literal += '\\\\'
|
|
294
294
|
else:
|
|
295
|
-
|
|
295
|
+
literal += c
|
|
296
296
|
|
|
297
|
-
if
|
|
298
|
-
|
|
299
|
-
yield
|
|
297
|
+
if literal:
|
|
298
|
+
literal += self.current_quote
|
|
299
|
+
yield literal
|
|
300
300
|
|
|
301
301
|
def __str__(self):
|
|
302
302
|
if self._s == '':
|
|
@@ -315,10 +315,10 @@ class Str(object):
|
|
|
315
315
|
for start_quote in self.allowed_quotes:
|
|
316
316
|
self.current_quote = start_quote
|
|
317
317
|
s = ''
|
|
318
|
-
for
|
|
319
|
-
if s and s[-1] ==
|
|
318
|
+
for literal in self._literals():
|
|
319
|
+
if s and s[-1] == literal[0]:
|
|
320
320
|
s += ' '
|
|
321
|
-
s +=
|
|
321
|
+
s += literal
|
|
322
322
|
|
|
323
323
|
if eval(s) == self._s:
|
|
324
324
|
candidates.append(s)
|
|
@@ -399,23 +399,23 @@ class Bytes(object):
|
|
|
399
399
|
raise ValueError("Couldn't find a quote")
|
|
400
400
|
|
|
401
401
|
def _literals(self):
|
|
402
|
-
|
|
402
|
+
literal = ''
|
|
403
403
|
for b in self._b:
|
|
404
404
|
if not self._can_quote(b):
|
|
405
|
-
if
|
|
406
|
-
|
|
407
|
-
yield
|
|
408
|
-
|
|
405
|
+
if literal:
|
|
406
|
+
literal += self.current_quote
|
|
407
|
+
yield literal
|
|
408
|
+
literal = ''
|
|
409
409
|
|
|
410
410
|
self.current_quote = self._get_quote(b)
|
|
411
411
|
|
|
412
|
-
if
|
|
413
|
-
|
|
414
|
-
|
|
412
|
+
if literal == '':
|
|
413
|
+
literal = 'b' + self.current_quote
|
|
414
|
+
literal += chr(b)
|
|
415
415
|
|
|
416
|
-
if
|
|
417
|
-
|
|
418
|
-
yield
|
|
416
|
+
if literal:
|
|
417
|
+
literal += self.current_quote
|
|
418
|
+
yield literal
|
|
419
419
|
|
|
420
420
|
def __str__(self):
|
|
421
421
|
if self._b == b'':
|
|
@@ -434,10 +434,10 @@ class Bytes(object):
|
|
|
434
434
|
for start_quote in self.allowed_quotes:
|
|
435
435
|
self.current_quote = start_quote
|
|
436
436
|
s = ''
|
|
437
|
-
for
|
|
438
|
-
if s and s[-1] ==
|
|
437
|
+
for literal in self._literals():
|
|
438
|
+
if s and s[-1] == literal[0]:
|
|
439
439
|
s += ' '
|
|
440
|
-
s +=
|
|
440
|
+
s += literal
|
|
441
441
|
|
|
442
442
|
assert eval(s) == self._b
|
|
443
443
|
candidates.append(s)
|
|
@@ -28,11 +28,15 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
28
28
|
assert isinstance(module, ast.Module)
|
|
29
29
|
|
|
30
30
|
self.visit_Module(module)
|
|
31
|
-
|
|
31
|
+
# On Python 2.7, preserve unicode strings to avoid encoding issues
|
|
32
|
+
code = unicode(self.printer) if sys.version_info[0] < 3 else str(self.printer)
|
|
33
|
+
return code.rstrip('\n' + self.indent_char + ';')
|
|
32
34
|
|
|
33
35
|
@property
|
|
34
36
|
def code(self):
|
|
35
|
-
|
|
37
|
+
# On Python 2.7, preserve unicode strings to avoid encoding issues
|
|
38
|
+
code = unicode(self.printer) if sys.version_info[0] < 3 else str(self.printer)
|
|
39
|
+
return code.rstrip('\n' + self.indent_char + ';')
|
|
36
40
|
|
|
37
41
|
# region Simple Statements
|
|
38
42
|
|
python_minifier/token_printer.py
CHANGED
|
@@ -91,7 +91,11 @@ class TokenPrinter(object):
|
|
|
91
91
|
self._prefer_single_line = prefer_single_line
|
|
92
92
|
self._allow_invalid_num_warnings = allow_invalid_num_warnings
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
# Initialize as unicode string on Python 2.7 to handle Unicode content
|
|
95
|
+
if sys.version_info[0] < 3:
|
|
96
|
+
self._code = u''
|
|
97
|
+
else:
|
|
98
|
+
self._code = ''
|
|
95
99
|
self.indent = 0
|
|
96
100
|
self.unicode_literals = False
|
|
97
101
|
self.previous_token = TokenTypes.NoToken
|
|
@@ -99,6 +103,10 @@ class TokenPrinter(object):
|
|
|
99
103
|
def __str__(self):
|
|
100
104
|
"""Return the output code."""
|
|
101
105
|
return self._code
|
|
106
|
+
|
|
107
|
+
def __unicode__(self):
|
|
108
|
+
"""Return the output code as unicode (for Python 2.7 compatibility)."""
|
|
109
|
+
return self._code
|
|
102
110
|
|
|
103
111
|
def identifier(self, name):
|
|
104
112
|
"""Add an identifier to the output code."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-minifier
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: Transform Python source code into it's most compact representation
|
|
5
5
|
Home-page: https://github.com/dflook/python-minifier
|
|
6
6
|
Author: Daniel Flook
|
|
@@ -130,7 +130,7 @@ def handler(event,context):
|
|
|
130
130
|
|
|
131
131
|
## Why?
|
|
132
132
|
|
|
133
|
-
AWS Cloudformation templates may have AWS lambda function source code embedded in them, but only if the function is less
|
|
133
|
+
AWS Cloudformation templates may have AWS lambda function source code embedded in them, but only if the function is less
|
|
134
134
|
than 4KiB. I wrote this package so I could write python normally and still embed the module in a template.
|
|
135
135
|
|
|
136
136
|
## Installation
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
python_minifier/__init__.py,sha256=
|
|
2
|
-
python_minifier/__init__.pyi,sha256
|
|
3
|
-
python_minifier/__main__.py,sha256=
|
|
4
|
-
python_minifier/ast_compare.py,sha256=
|
|
1
|
+
python_minifier/__init__.py,sha256=Q95ufDbd7hadjVtJZYclsJqX9S4NsKZSpqCui0Fw7oI,9542
|
|
2
|
+
python_minifier/__init__.pyi,sha256=-xLoKXbQsV7ko_YzyXL9WkI2vmGc6yn4AW5biK_GJXE,1233
|
|
3
|
+
python_minifier/__main__.py,sha256=r7_Vh9n-aoc4jd5CERKO3KqJeqXHeWoycDRlvV7xTFM,14053
|
|
4
|
+
python_minifier/ast_compare.py,sha256=TlkEdQyiEXZZxbu3NrOgmYE7d8nV8dYhHDMysni44-Q,3249
|
|
5
5
|
python_minifier/ast_compat.py,sha256=nubno_yFHtuoxbT7a7CtlcAfdNj9yhniKSfNoOsQ3Fw,2209
|
|
6
6
|
python_minifier/ast_printer.py,sha256=TlkyKl9_9ScWeop3W1TwXZ46MJWINfkJ7NvmULpwt4A,3254
|
|
7
7
|
python_minifier/expression_printer.py,sha256=AwkDTs-NJhLyDppE_zlgQdtQQTVQlxdOdgTtSt_DxT8,22465
|
|
8
|
-
python_minifier/f_string.py,sha256=
|
|
8
|
+
python_minifier/f_string.py,sha256=9Zkb2SksoTdx0-dfQKy_Q76KrOR4cxPokR5tnF7jldY,14131
|
|
9
9
|
python_minifier/ministring.py,sha256=R0xaAZqMlLu1Jm0aBVSI0n8KZiZV7PTs4RE4UbCmTy8,4359
|
|
10
|
-
python_minifier/module_printer.py,sha256=
|
|
10
|
+
python_minifier/module_printer.py,sha256=CZFZ3WDBgH57_Q2pmC0ySFdRcvQR_7uVQeXKfvT1BN0,25566
|
|
11
11
|
python_minifier/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
python_minifier/token_printer.py,sha256=
|
|
12
|
+
python_minifier/token_printer.py,sha256=TbN7VDGM_icmruLnBLgtWpHz1iY4pagGKsWCBMWSisA,9640
|
|
13
13
|
python_minifier/util.py,sha256=60iT3XkKlPlZhXQ1NuLB27Wv3ihl-gBC_WjOjEiFn-Q,1184
|
|
14
14
|
python_minifier/ast_annotation/__init__.py,sha256=BJ4gyS-_bytIZf0SP8JJG6FECWf8MUaUi3vOAfD60qQ,2259
|
|
15
15
|
python_minifier/rename/__init__.py,sha256=8DLEFgliakf_5T_m-l1Nd35QxKpM4h7RJyFVpjsxjWA,375
|
|
@@ -36,10 +36,10 @@ python_minifier/transforms/remove_object_base.py,sha256=j4se6OXyZK1lr_ABmGT0Oivu
|
|
|
36
36
|
python_minifier/transforms/remove_pass.py,sha256=S9e59nBEZ8rBBifvAhbPRDTfUA7s8_a7pSIsZbFZD2A,735
|
|
37
37
|
python_minifier/transforms/remove_posargs.py,sha256=aV0wFnGiDXu4uQBQP7-cB1uLSF3mamIq5-txvDg8BVo,314
|
|
38
38
|
python_minifier/transforms/suite_transformer.py,sha256=WZCVkkBSniWeEtBybVweeMmy-A1wC3lBIYSgxCHelBU,6324
|
|
39
|
-
python_minifier-
|
|
40
|
-
python_minifier-
|
|
41
|
-
python_minifier-
|
|
42
|
-
python_minifier-
|
|
43
|
-
python_minifier-
|
|
44
|
-
python_minifier-
|
|
45
|
-
python_minifier-
|
|
39
|
+
python_minifier-3.0.0.dist-info/LICENSE,sha256=FzsyDHb8pAZupSGFjIOuHcHMlFf6N-aIxq9gOYGbNyE,1069
|
|
40
|
+
python_minifier-3.0.0.dist-info/METADATA,sha256=qyng9Qp0kOp9hiup4wcfJW2DQJT3_hCjbFemSrIpTpU,6451
|
|
41
|
+
python_minifier-3.0.0.dist-info/WHEEL,sha256=1VPi6hfNQaRRNuEdK_3dv9o8COtLGnHWJghhj4CQ28k,92
|
|
42
|
+
python_minifier-3.0.0.dist-info/entry_points.txt,sha256=aS7ZUWQeeys8lAbrmmEa2__Bg-anH1tUMyi9cKdTbO4,60
|
|
43
|
+
python_minifier-3.0.0.dist-info/top_level.txt,sha256=4SRDfWKi_KMq7LDrjlzUFoDCs6INYPtxc1Pun4z8LsU,16
|
|
44
|
+
python_minifier-3.0.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
45
|
+
python_minifier-3.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|