python-minifier 2.10.0__tar.gz → 2.11.1__tar.gz

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.
Files changed (84) hide show
  1. {python_minifier-2.10.0/src/python_minifier.egg-info → python_minifier-2.11.1}/PKG-INFO +12 -7
  2. {python_minifier-2.10.0 → python_minifier-2.11.1}/README.md +8 -5
  3. {python_minifier-2.10.0 → python_minifier-2.11.1}/setup.py +4 -2
  4. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/ministring.py +7 -3
  5. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/module_printer.py +12 -0
  6. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_annotations.py +2 -2
  7. {python_minifier-2.10.0 → python_minifier-2.11.1/src/python_minifier.egg-info}/PKG-INFO +12 -7
  8. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier.egg-info/SOURCES.txt +4 -1
  9. python_minifier-2.11.1/test/test_bind_names_python312.py +158 -0
  10. python_minifier-2.11.1/test/test_bind_names_python313.py +189 -0
  11. python_minifier-2.11.1/test/test_type_param_defaults.py +89 -0
  12. {python_minifier-2.10.0 → python_minifier-2.11.1}/LICENSE +0 -0
  13. {python_minifier-2.10.0 → python_minifier-2.11.1}/setup.cfg +0 -0
  14. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/__init__.py +0 -0
  15. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/__init__.pyi +0 -0
  16. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/__main__.py +0 -0
  17. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/ast_compare.py +0 -0
  18. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/ast_compat.py +0 -0
  19. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/ast_printer.py +0 -0
  20. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/expression_printer.py +0 -0
  21. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/f_string.py +0 -0
  22. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/py.typed +0 -0
  23. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/__init__.py +0 -0
  24. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/bind_names.py +0 -0
  25. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/binding.py +0 -0
  26. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/mapper.py +0 -0
  27. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/name_generator.py +0 -0
  28. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/rename_literals.py +0 -0
  29. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/renamer.py +0 -0
  30. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/resolve_names.py +0 -0
  31. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/rename/util.py +0 -0
  32. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/token_printer.py +0 -0
  33. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/__init__.py +0 -0
  34. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/combine_imports.py +0 -0
  35. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/constant_folding.py +0 -0
  36. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_annotations_options.py +0 -0
  37. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_annotations_options.pyi +0 -0
  38. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_asserts.py +0 -0
  39. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_debug.py +0 -0
  40. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_exception_brackets.py +0 -0
  41. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_explicit_return_none.py +0 -0
  42. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_literal_statements.py +0 -0
  43. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_object_base.py +0 -0
  44. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_pass.py +0 -0
  45. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/remove_posargs.py +0 -0
  46. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/transforms/suite_transformer.py +0 -0
  47. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier/util.py +0 -0
  48. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier.egg-info/dependency_links.txt +0 -0
  49. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier.egg-info/entry_points.txt +0 -0
  50. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier.egg-info/top_level.txt +0 -0
  51. {python_minifier-2.10.0 → python_minifier-2.11.1}/src/python_minifier.egg-info/zip-safe +0 -0
  52. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_assignment_expressions.py +0 -0
  53. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_await_fstring.py +0 -0
  54. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_bind_names.py +0 -0
  55. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_bind_names_python2.py +0 -0
  56. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_bind_names_python33.py +0 -0
  57. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_combine_imports.py +0 -0
  58. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_comprehension_rename.py +0 -0
  59. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_decorator_expressions.py +0 -0
  60. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_dict_expansion.py +0 -0
  61. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_folding.py +0 -0
  62. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_fstring.py +0 -0
  63. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_generic_types.py +0 -0
  64. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_hoist_literals.py +0 -0
  65. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_import.py +0 -0
  66. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_is_ast_node.py +0 -0
  67. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_iterable_unpacking.py +0 -0
  68. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_match.py +0 -0
  69. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_match_rename.py +0 -0
  70. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_name_generator.py +0 -0
  71. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_nonlocal.py +0 -0
  72. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_posargs.py +0 -0
  73. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_preserve_shebang.py +0 -0
  74. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_remove_annotations.py +0 -0
  75. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_remove_assert.py +0 -0
  76. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_remove_debug.py +0 -0
  77. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_remove_exception_brackets.py +0 -0
  78. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_remove_explicit_return_none.py +0 -0
  79. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_remove_literal_statements.py +0 -0
  80. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_remove_object.py +0 -0
  81. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_remove_pass.py +0 -0
  82. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_rename_builtins.py +0 -0
  83. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_rename_locals.py +0 -0
  84. {python_minifier-2.10.0 → python_minifier-2.11.1}/test/test_slice.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python_minifier
3
- Version: 2.10.0
3
+ Version: 2.11.1
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
@@ -8,6 +8,7 @@ Author-email: daniel@flook.org
8
8
  License: MIT
9
9
  Project-URL: Issues, https://github.com/dflook/python-minifier/issues
10
10
  Project-URL: Documentation, https://dflook.github.io/python-minifier/
11
+ Project-URL: Changelog, https://github.com/dflook/python-minifier/blob/main/CHANGELOG.md
11
12
  Keywords: minify minifier
12
13
  Classifier: Development Status :: 5 - Production/Stable
13
14
  Classifier: License :: OSI Approved :: MIT License
@@ -23,13 +24,14 @@ Classifier: Programming Language :: Python :: 3.9
23
24
  Classifier: Programming Language :: Python :: 3.10
24
25
  Classifier: Programming Language :: Python :: 3.11
25
26
  Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Programming Language :: Python :: 3.13
26
28
  Classifier: Programming Language :: Python :: 2
27
29
  Classifier: Programming Language :: Python :: 2.7
28
30
  Classifier: Programming Language :: Python :: Implementation :: CPython
29
31
  Classifier: Programming Language :: Python :: Implementation :: PyPy
30
32
  Classifier: Intended Audience :: Developers
31
33
  Classifier: Topic :: Software Development
32
- Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <3.13
34
+ Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <3.14
33
35
  Description-Content-Type: text/markdown
34
36
  License-File: LICENSE
35
37
 
@@ -39,7 +41,7 @@ Transforms Python source code into its most compact representation.
39
41
 
40
42
  [Try it out!](https://python-minifier.com)
41
43
 
42
- python-minifier currently supports Python 2.7 and Python 3.3 to 3.12. Previous releases supported Python 2.6.
44
+ python-minifier currently supports Python 2.7 and Python 3.3 to 3.13. Previous releases supported Python 2.6.
43
45
 
44
46
  * [PyPI](https://pypi.org/project/python-minifier/)
45
47
  * [Documentation](https://dflook.github.io/python-minifier/)
@@ -139,10 +141,13 @@ To install python-minifier use pip:
139
141
  $ pip install python-minifier
140
142
  ```
141
143
 
142
- Note that python-minifier depends on the python interpreter for parsing source code,
143
- so install using a version of python appropriate for your source.
144
+ Note that python-minifier depends on the python interpreter for parsing source code,
145
+ and outputs source code compatible with the version of the interpreter it is run with.
144
146
 
145
- python-minifier runs with and can minify code written for Python 2.7 and Python 3.3 to 3.12.
147
+ This means that if you minify code written for Python 3.11 using python-minifier running with Python 3.12,
148
+ the minified code may only run with Python 3.12.
149
+
150
+ python-minifier runs with and can minify code written for Python 2.7 and Python 3.3 to 3.13.
146
151
 
147
152
  ## Usage
148
153
 
@@ -167,4 +172,4 @@ Documentation is available at [dflook.github.io/python-minifier/](https://dflook
167
172
 
168
173
  Available under the MIT License. Full text is in the [LICENSE](LICENSE) file.
169
174
 
170
- Copyright (c) 2020 Daniel Flook
175
+ Copyright (c) 2024 Daniel Flook
@@ -4,7 +4,7 @@ Transforms Python source code into its most compact representation.
4
4
 
5
5
  [Try it out!](https://python-minifier.com)
6
6
 
7
- python-minifier currently supports Python 2.7 and Python 3.3 to 3.12. Previous releases supported Python 2.6.
7
+ python-minifier currently supports Python 2.7 and Python 3.3 to 3.13. Previous releases supported Python 2.6.
8
8
 
9
9
  * [PyPI](https://pypi.org/project/python-minifier/)
10
10
  * [Documentation](https://dflook.github.io/python-minifier/)
@@ -104,10 +104,13 @@ To install python-minifier use pip:
104
104
  $ pip install python-minifier
105
105
  ```
106
106
 
107
- Note that python-minifier depends on the python interpreter for parsing source code,
108
- so install using a version of python appropriate for your source.
107
+ Note that python-minifier depends on the python interpreter for parsing source code,
108
+ and outputs source code compatible with the version of the interpreter it is run with.
109
109
 
110
- python-minifier runs with and can minify code written for Python 2.7 and Python 3.3 to 3.12.
110
+ This means that if you minify code written for Python 3.11 using python-minifier running with Python 3.12,
111
+ the minified code may only run with Python 3.12.
112
+
113
+ python-minifier runs with and can minify code written for Python 2.7 and Python 3.3 to 3.13.
111
114
 
112
115
  ## Usage
113
116
 
@@ -132,4 +135,4 @@ Documentation is available at [dflook.github.io/python-minifier/](https://dflook
132
135
 
133
136
  Available under the MIT License. Full text is in the [LICENSE](LICENSE) file.
134
137
 
135
- Copyright (c) 2020 Daniel Flook
138
+ Copyright (c) 2024 Daniel Flook
@@ -16,6 +16,7 @@ setup(
16
16
  project_urls={
17
17
  'Issues': 'https://github.com/dflook/python-minifier/issues',
18
18
  'Documentation': 'https://dflook.github.io/python-minifier/',
19
+ 'Changelog': 'https://github.com/dflook/python-minifier/blob/main/CHANGELOG.md'
19
20
  },
20
21
  keywords='minify minifier',
21
22
 
@@ -26,8 +27,8 @@ setup(
26
27
  long_description=long_desc,
27
28
  long_description_content_type='text/markdown',
28
29
 
29
- python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <3.13',
30
- version='2.10.0',
30
+ python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <3.14',
31
+ version='2.11.1',
31
32
 
32
33
  classifiers=[
33
34
  'Development Status :: 5 - Production/Stable',
@@ -44,6 +45,7 @@ setup(
44
45
  'Programming Language :: Python :: 3.10',
45
46
  'Programming Language :: Python :: 3.11',
46
47
  'Programming Language :: Python :: 3.12',
48
+ 'Programming Language :: Python :: 3.13',
47
49
  'Programming Language :: Python :: 2',
48
50
  'Programming Language :: Python :: 2.7',
49
51
  'Programming Language :: Python :: Implementation :: CPython',
@@ -32,11 +32,15 @@ class MiniString(object):
32
32
 
33
33
  try:
34
34
  eval(self.quote + s + self.quote)
35
- except UnicodeDecodeError:
36
- if self._safe_mode:
35
+ except (UnicodeDecodeError, UnicodeEncodeError) as e:
36
+ if self.safe_mode:
37
37
  raise
38
38
 
39
- self._safe_mode = True
39
+ self.safe_mode = True
40
+ if len(self.quote) == 1:
41
+ s = self.to_short()
42
+ else:
43
+ s = self.to_long()
40
44
 
41
45
  assert eval(self.quote + s + self.quote) == self._s
42
46
 
@@ -754,17 +754,29 @@ class ModulePrinter(ExpressionPrinter):
754
754
  self.printer.delimiter(':')
755
755
  self._expression(node.bound)
756
756
 
757
+ if hasattr(node, 'default_value') and node.default_value is not None:
758
+ self.printer.delimiter('=')
759
+ self._expression(node.default_value)
760
+
757
761
  def visit_TypeVarTuple(self, node):
758
762
  assert isinstance(node, ast.TypeVarTuple)
759
763
  self.printer.operator('*')
760
764
  self.printer.identifier(node.name)
761
765
 
766
+ if hasattr(node, 'default_value') and node.default_value is not None:
767
+ self.printer.delimiter('=')
768
+ self._expression(node.default_value)
769
+
762
770
  def visit_ParamSpec(self, node):
763
771
  assert isinstance(node, ast.ParamSpec)
764
772
  self.printer.operator('*')
765
773
  self.printer.operator('*')
766
774
  self.printer.identifier(node.name)
767
775
 
776
+ if hasattr(node, 'default_value') and node.default_value is not None:
777
+ self.printer.delimiter('=')
778
+ self._expression(node.default_value)
779
+
768
780
  # endregion
769
781
 
770
782
  def visit_Module(self, node):
@@ -120,11 +120,11 @@ class RemoveAnnotations(SuiteTransformer):
120
120
  if is_dataclass_field(node) or is_typing_sensitive(node):
121
121
  return node
122
122
  elif node.value:
123
- return self.add_child(ast.Assign([node.target], node.value), parent=node.parent)
123
+ return self.add_child(ast.Assign([node.target], node.value), parent=node.parent, namespace=node.namespace)
124
124
  else:
125
125
  # Valueless annotations cause the interpreter to treat the variable as a local.
126
126
  # I don't know of another way to do that without assigning to it, so
127
127
  # keep it as an AnnAssign, but replace the annotation with '0'
128
128
 
129
- node.annotation = self.add_child(ast.Num(0), parent=node.parent)
129
+ node.annotation = self.add_child(ast.Num(0), parent=node.parent, namespace=node.namespace)
130
130
  return node
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python_minifier
3
- Version: 2.10.0
3
+ Version: 2.11.1
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
@@ -8,6 +8,7 @@ Author-email: daniel@flook.org
8
8
  License: MIT
9
9
  Project-URL: Issues, https://github.com/dflook/python-minifier/issues
10
10
  Project-URL: Documentation, https://dflook.github.io/python-minifier/
11
+ Project-URL: Changelog, https://github.com/dflook/python-minifier/blob/main/CHANGELOG.md
11
12
  Keywords: minify minifier
12
13
  Classifier: Development Status :: 5 - Production/Stable
13
14
  Classifier: License :: OSI Approved :: MIT License
@@ -23,13 +24,14 @@ Classifier: Programming Language :: Python :: 3.9
23
24
  Classifier: Programming Language :: Python :: 3.10
24
25
  Classifier: Programming Language :: Python :: 3.11
25
26
  Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Programming Language :: Python :: 3.13
26
28
  Classifier: Programming Language :: Python :: 2
27
29
  Classifier: Programming Language :: Python :: 2.7
28
30
  Classifier: Programming Language :: Python :: Implementation :: CPython
29
31
  Classifier: Programming Language :: Python :: Implementation :: PyPy
30
32
  Classifier: Intended Audience :: Developers
31
33
  Classifier: Topic :: Software Development
32
- Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <3.13
34
+ Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <3.14
33
35
  Description-Content-Type: text/markdown
34
36
  License-File: LICENSE
35
37
 
@@ -39,7 +41,7 @@ Transforms Python source code into its most compact representation.
39
41
 
40
42
  [Try it out!](https://python-minifier.com)
41
43
 
42
- python-minifier currently supports Python 2.7 and Python 3.3 to 3.12. Previous releases supported Python 2.6.
44
+ python-minifier currently supports Python 2.7 and Python 3.3 to 3.13. Previous releases supported Python 2.6.
43
45
 
44
46
  * [PyPI](https://pypi.org/project/python-minifier/)
45
47
  * [Documentation](https://dflook.github.io/python-minifier/)
@@ -139,10 +141,13 @@ To install python-minifier use pip:
139
141
  $ pip install python-minifier
140
142
  ```
141
143
 
142
- Note that python-minifier depends on the python interpreter for parsing source code,
143
- so install using a version of python appropriate for your source.
144
+ Note that python-minifier depends on the python interpreter for parsing source code,
145
+ and outputs source code compatible with the version of the interpreter it is run with.
144
146
 
145
- python-minifier runs with and can minify code written for Python 2.7 and Python 3.3 to 3.12.
147
+ This means that if you minify code written for Python 3.11 using python-minifier running with Python 3.12,
148
+ the minified code may only run with Python 3.12.
149
+
150
+ python-minifier runs with and can minify code written for Python 2.7 and Python 3.3 to 3.13.
146
151
 
147
152
  ## Usage
148
153
 
@@ -167,4 +172,4 @@ Documentation is available at [dflook.github.io/python-minifier/](https://dflook
167
172
 
168
173
  Available under the MIT License. Full text is in the [LICENSE](LICENSE) file.
169
174
 
170
- Copyright (c) 2020 Daniel Flook
175
+ Copyright (c) 2024 Daniel Flook
@@ -48,6 +48,8 @@ test/test_assignment_expressions.py
48
48
  test/test_await_fstring.py
49
49
  test/test_bind_names.py
50
50
  test/test_bind_names_python2.py
51
+ test/test_bind_names_python312.py
52
+ test/test_bind_names_python313.py
51
53
  test/test_bind_names_python33.py
52
54
  test/test_combine_imports.py
53
55
  test/test_comprehension_rename.py
@@ -76,4 +78,5 @@ test/test_remove_object.py
76
78
  test/test_remove_pass.py
77
79
  test/test_rename_builtins.py
78
80
  test/test_rename_locals.py
79
- test/test_slice.py
81
+ test/test_slice.py
82
+ test/test_type_param_defaults.py
@@ -0,0 +1,158 @@
1
+ import sys
2
+
3
+ import pytest
4
+
5
+ from helpers import assert_namespace_tree
6
+
7
+ def test_class_typevar_default():
8
+ if sys.version_info < (3, 12):
9
+ pytest.skip('Test is for > python3.12 only')
10
+
11
+ source = '''
12
+ class Foo[T]: ...
13
+ '''
14
+
15
+ expected_namespaces = '''
16
+ + Module
17
+ - NameBinding(name='Foo', allow_rename=True) <references=1>
18
+ - NameBinding(name='T', allow_rename=True) <references=1>
19
+ + Class Foo
20
+ '''
21
+
22
+ assert_namespace_tree(source, expected_namespaces)
23
+
24
+ def test_function_typevar_default():
25
+ if sys.version_info < (3, 12):
26
+ pytest.skip('Test is for > python3.12 only')
27
+
28
+ source = '''
29
+ def foo[T](): ...
30
+ '''
31
+
32
+ expected_namespaces = '''
33
+ + Module
34
+ - NameBinding(name='T', allow_rename=True) <references=1>
35
+ - NameBinding(name='foo', allow_rename=True) <references=1>
36
+ + Function foo
37
+ '''
38
+
39
+ assert_namespace_tree(source, expected_namespaces)
40
+
41
+ def test_alias_typevar_default():
42
+ if sys.version_info < (3, 12):
43
+ pytest.skip('Test is for > python3.12 only')
44
+
45
+ source = '''
46
+ type Alias[DefaultT] = Blah
47
+ '''
48
+
49
+ expected_namespaces = '''
50
+ + Module
51
+ - NameBinding(name='Alias', allow_rename=True) <references=1>
52
+ - NameBinding(name='Blah', allow_rename=False) <references=1>
53
+ - NameBinding(name='DefaultT', allow_rename=True) <references=1>
54
+ '''
55
+
56
+ assert_namespace_tree(source, expected_namespaces)
57
+
58
+ def test_class_typevartuple_default():
59
+ if sys.version_info < (3, 12):
60
+ pytest.skip('Test is for > python3.12 only')
61
+
62
+ source = '''
63
+ class Foo[*T]: ...
64
+ '''
65
+
66
+ expected_namespaces = '''
67
+ + Module
68
+ - NameBinding(name='Foo', allow_rename=True) <references=1>
69
+ - NameBinding(name='T', allow_rename=True) <references=1>
70
+ + Class Foo
71
+ '''
72
+
73
+ assert_namespace_tree(source, expected_namespaces)
74
+
75
+ def test_function_typevartuple_default():
76
+ if sys.version_info < (3, 12):
77
+ pytest.skip('Test is for > python3.12 only')
78
+
79
+ source = '''
80
+ def foo[*T](): ...
81
+ '''
82
+
83
+ expected_namespaces = '''
84
+ + Module
85
+ - NameBinding(name='T', allow_rename=True) <references=1>
86
+ - NameBinding(name='foo', allow_rename=True) <references=1>
87
+ + Function foo
88
+ '''
89
+
90
+ assert_namespace_tree(source, expected_namespaces)
91
+
92
+ def test_alias_typevartuple_default():
93
+ if sys.version_info < (3, 12):
94
+ pytest.skip('Test is for > python3.12 only')
95
+
96
+ source = '''
97
+ type Alias[*DefaultT] = Blah
98
+ '''
99
+
100
+ expected_namespaces = '''
101
+ + Module
102
+ - NameBinding(name='Alias', allow_rename=True) <references=1>
103
+ - NameBinding(name='Blah', allow_rename=False) <references=1>
104
+ - NameBinding(name='DefaultT', allow_rename=True) <references=1>
105
+ '''
106
+
107
+ assert_namespace_tree(source, expected_namespaces)
108
+
109
+ def test_class_paramspec_default():
110
+ if sys.version_info < (3, 12):
111
+ pytest.skip('Test is for > python3.12 only')
112
+
113
+ source = '''
114
+ class Foo[**T]: ...
115
+ '''
116
+
117
+ expected_namespaces = '''
118
+ + Module
119
+ - NameBinding(name='Foo', allow_rename=True) <references=1>
120
+ - NameBinding(name='T', allow_rename=True) <references=1>
121
+ + Class Foo
122
+ '''
123
+
124
+ assert_namespace_tree(source, expected_namespaces)
125
+
126
+ def test_function_paramspec_default():
127
+ if sys.version_info < (3, 12):
128
+ pytest.skip('Test is for > python3.12 only')
129
+
130
+ source = '''
131
+ def foo[**T](): ...
132
+ '''
133
+
134
+ expected_namespaces = '''
135
+ + Module
136
+ - NameBinding(name='T', allow_rename=True) <references=1>
137
+ - NameBinding(name='foo', allow_rename=True) <references=1>
138
+ + Function foo
139
+ '''
140
+
141
+ assert_namespace_tree(source, expected_namespaces)
142
+
143
+ def test_alias_paramspec_default():
144
+ if sys.version_info < (3, 12):
145
+ pytest.skip('Test is for > python3.12 only')
146
+
147
+ source = '''
148
+ type Alias[**DefaultT] = Blah
149
+ '''
150
+
151
+ expected_namespaces = '''
152
+ + Module
153
+ - NameBinding(name='Alias', allow_rename=True) <references=1>
154
+ - NameBinding(name='Blah', allow_rename=False) <references=1>
155
+ - NameBinding(name='DefaultT', allow_rename=True) <references=1>
156
+ '''
157
+
158
+ assert_namespace_tree(source, expected_namespaces)
@@ -0,0 +1,189 @@
1
+ import sys
2
+
3
+ import pytest
4
+
5
+ from helpers import assert_namespace_tree
6
+
7
+ def test_class_typevar_default():
8
+ if sys.version_info < (3, 13):
9
+ pytest.skip('Test is for python3.13 only')
10
+
11
+ source = '''
12
+ class Foo[T = str]: ...
13
+ '''
14
+
15
+ expected_namespaces = '''
16
+ + Module
17
+ - NameBinding(name='Foo', allow_rename=True) <references=1>
18
+ - NameBinding(name='T', allow_rename=True) <references=1>
19
+ - BuiltinBinding(name='str', allow_rename=True) <references=1>
20
+ + Class Foo
21
+ '''
22
+
23
+ assert_namespace_tree(source, expected_namespaces)
24
+
25
+ def test_function_typevar_default():
26
+ if sys.version_info < (3, 13):
27
+ pytest.skip('Test is for python3.13 only')
28
+
29
+ source = '''
30
+ A = str
31
+ def foo[T = A](): ...
32
+ '''
33
+
34
+ expected_namespaces = '''
35
+ + Module
36
+ - NameBinding(name='A', allow_rename=True) <references=2>
37
+ - NameBinding(name='T', allow_rename=True) <references=1>
38
+ - NameBinding(name='foo', allow_rename=True) <references=1>
39
+ - BuiltinBinding(name='str', allow_rename=True) <references=1>
40
+ + Function foo
41
+ '''
42
+
43
+ assert_namespace_tree(source, expected_namespaces)
44
+
45
+ def test_alias_typevar_default():
46
+ if sys.version_info < (3, 13):
47
+ pytest.skip('Test is for python3.13 only')
48
+
49
+ source = '''
50
+ A = str
51
+ type Alias[DefaultT = A] = Blah
52
+ '''
53
+
54
+ expected_namespaces = '''
55
+ + Module
56
+ - NameBinding(name='A', allow_rename=True) <references=2>
57
+ - NameBinding(name='Alias', allow_rename=True) <references=1>
58
+ - NameBinding(name='Blah', allow_rename=False) <references=1>
59
+ - NameBinding(name='DefaultT', allow_rename=True) <references=1>
60
+ - BuiltinBinding(name='str', allow_rename=True) <references=1>
61
+ '''
62
+
63
+ assert_namespace_tree(source, expected_namespaces)
64
+
65
+ def test_class_typevartuple_default():
66
+ if sys.version_info < (3, 13):
67
+ pytest.skip('Test is for python3.13 only')
68
+
69
+ source = '''
70
+ T=tuple[str, int]
71
+ class Foo[*T = str]: ...
72
+ '''
73
+
74
+ expected_namespaces = '''
75
+ + Module
76
+ - NameBinding(name='Foo', allow_rename=True) <references=1>
77
+ - NameBinding(name='T', allow_rename=True) <references=2>
78
+ - BuiltinBinding(name='int', allow_rename=True) <references=1>
79
+ - BuiltinBinding(name='str', allow_rename=True) <references=2>
80
+ - BuiltinBinding(name='tuple', allow_rename=True) <references=1>
81
+ + Class Foo
82
+ '''
83
+
84
+ assert_namespace_tree(source, expected_namespaces)
85
+
86
+ def test_function_typevartuple_default():
87
+ if sys.version_info < (3, 13):
88
+ pytest.skip('Test is for python3.13 only')
89
+
90
+ source = '''
91
+ A = tuple[str, int]
92
+ def foo[*T = A](): ...
93
+ '''
94
+
95
+ expected_namespaces = '''
96
+ + Module
97
+ - NameBinding(name='A', allow_rename=True) <references=2>
98
+ - NameBinding(name='T', allow_rename=True) <references=1>
99
+ - NameBinding(name='foo', allow_rename=True) <references=1>
100
+ - BuiltinBinding(name='int', allow_rename=True) <references=1>
101
+ - BuiltinBinding(name='str', allow_rename=True) <references=1>
102
+ - BuiltinBinding(name='tuple', allow_rename=True) <references=1>
103
+ + Function foo
104
+ '''
105
+
106
+ assert_namespace_tree(source, expected_namespaces)
107
+
108
+ def test_alias_typevartuple_default():
109
+ if sys.version_info < (3, 13):
110
+ pytest.skip('Test is for python3.13 only')
111
+
112
+ source = '''
113
+ type Alias[*DefaultT = tuple[str, int]] = Blah
114
+ '''
115
+
116
+ expected_namespaces = '''
117
+ + Module
118
+ - NameBinding(name='Alias', allow_rename=True) <references=1>
119
+ - NameBinding(name='Blah', allow_rename=False) <references=1>
120
+ - NameBinding(name='DefaultT', allow_rename=True) <references=1>
121
+ - BuiltinBinding(name='int', allow_rename=True) <references=1>
122
+ - BuiltinBinding(name='str', allow_rename=True) <references=1>
123
+ - BuiltinBinding(name='tuple', allow_rename=True) <references=1>
124
+ '''
125
+
126
+ assert_namespace_tree(source, expected_namespaces)
127
+
128
+ def test_class_paramspec_default():
129
+ if sys.version_info < (3, 13):
130
+ pytest.skip('Test is for python3.13 only')
131
+
132
+ source = '''
133
+ T=tuple[str, int]
134
+ class Foo[**T = str]: ...
135
+ '''
136
+
137
+ expected_namespaces = '''
138
+ + Module
139
+ - NameBinding(name='Foo', allow_rename=True) <references=1>
140
+ - NameBinding(name='T', allow_rename=True) <references=2>
141
+ - BuiltinBinding(name='int', allow_rename=True) <references=1>
142
+ - BuiltinBinding(name='str', allow_rename=True) <references=2>
143
+ - BuiltinBinding(name='tuple', allow_rename=True) <references=1>
144
+ + Class Foo
145
+ '''
146
+
147
+ assert_namespace_tree(source, expected_namespaces)
148
+
149
+ def test_function_paramspec_default():
150
+ if sys.version_info < (3, 13):
151
+ pytest.skip('Test is for python3.13 only')
152
+
153
+ source = '''
154
+ A = tuple[str, int]
155
+ def foo[**T = A](): ...
156
+ '''
157
+
158
+ expected_namespaces = '''
159
+ + Module
160
+ - NameBinding(name='A', allow_rename=True) <references=2>
161
+ - NameBinding(name='T', allow_rename=True) <references=1>
162
+ - NameBinding(name='foo', allow_rename=True) <references=1>
163
+ - BuiltinBinding(name='int', allow_rename=True) <references=1>
164
+ - BuiltinBinding(name='str', allow_rename=True) <references=1>
165
+ - BuiltinBinding(name='tuple', allow_rename=True) <references=1>
166
+ + Function foo
167
+ '''
168
+
169
+ assert_namespace_tree(source, expected_namespaces)
170
+
171
+ def test_alias_paramspec_default():
172
+ if sys.version_info < (3, 13):
173
+ pytest.skip('Test is for python3.13 only')
174
+
175
+ source = '''
176
+ type Alias[**DefaultT = tuple[str, int]] = Blah
177
+ '''
178
+
179
+ expected_namespaces = '''
180
+ + Module
181
+ - NameBinding(name='Alias', allow_rename=True) <references=1>
182
+ - NameBinding(name='Blah', allow_rename=False) <references=1>
183
+ - NameBinding(name='DefaultT', allow_rename=True) <references=1>
184
+ - BuiltinBinding(name='int', allow_rename=True) <references=1>
185
+ - BuiltinBinding(name='str', allow_rename=True) <references=1>
186
+ - BuiltinBinding(name='tuple', allow_rename=True) <references=1>
187
+ '''
188
+
189
+ assert_namespace_tree(source, expected_namespaces)
@@ -0,0 +1,89 @@
1
+ import ast
2
+ import sys
3
+ import pytest
4
+ from python_minifier import unparse
5
+ from python_minifier.ast_compare import compare_ast
6
+
7
+ # There are bizarrely few examples of this, some in the PEP are even syntax errors
8
+
9
+ def test_pep696():
10
+ if sys.version_info < (3, 13):
11
+ pytest.skip('Defaults for type parameters are not supported in python < 3.13')
12
+
13
+ source = '''
14
+ type Alias[DefaultT = int, T] = tuple[DefaultT, T] # SyntaxError: non-default TypeVars cannot follow ones with defaults
15
+
16
+ def generic_func[DefaultT = int, T](x: DefaultT, y: T) -> None: ... # SyntaxError: non-default TypeVars cannot follow ones with defaults
17
+
18
+ class GenericClass[DefaultT = int, T]: ... # SyntaxError: non-default TypeVars cannot follow ones with defaults
19
+
20
+ '''
21
+
22
+ expected_ast = ast.parse(source)
23
+ actual_ast = unparse(expected_ast)
24
+ compare_ast(expected_ast, ast.parse(actual_ast))
25
+
26
+ def test_pep696_2():
27
+ if sys.version_info < (3, 13):
28
+ pytest.skip('Defaults for type parameters are not supported in python < 3.13')
29
+
30
+ source = '''
31
+ # TypeVars
32
+ class Foo[T = str]: ...
33
+
34
+ # ParamSpecs
35
+ class Baz[**P = [int, str]]: ...
36
+
37
+ # TypeVarTuples
38
+ class Qux[*Ts = *tuple[int, bool]]: ...
39
+
40
+ # TypeAliases
41
+ type Qux[*Ts = *tuple[str]] = Ham[*Ts]
42
+ type Rab[U, T = str] = Bar[T, U]
43
+ '''
44
+
45
+ expected_ast = ast.parse(source)
46
+ actual_ast = unparse(expected_ast)
47
+ compare_ast(expected_ast, ast.parse(actual_ast))
48
+
49
+ def test_pep696_3():
50
+ if sys.version_info < (3, 13):
51
+ pytest.skip('Defaults for type parameters are not supported in python < 3.13')
52
+
53
+ source = '''
54
+ class Foo[T = int]:
55
+ def meth(self) -> Self:
56
+ return self
57
+
58
+ reveal_type(Foo.meth) # type is (self: Foo[int]) -> Foo[int]
59
+
60
+ '''
61
+
62
+ expected_ast = ast.parse(source)
63
+ actual_ast = unparse(expected_ast)
64
+ compare_ast(expected_ast, ast.parse(actual_ast))
65
+
66
+ def test_example():
67
+ if sys.version_info < (3, 13):
68
+ pytest.skip('Defaults for type parameters are not supported in python < 3.13')
69
+
70
+ source = '''
71
+ def overly_generic[
72
+ SimpleTypeVar,
73
+ TypeVarWithDefault = int,
74
+ TypeVarWithBound: int,
75
+ TypeVarWithConstraints: (str, bytes),
76
+ *SimpleTypeVarTuple = (int, float),
77
+ **SimpleParamSpec = (str, bytearray),
78
+ ](
79
+ a: SimpleTypeVar,
80
+ b: TypeVarWithDefault,
81
+ c: TypeVarWithBound,
82
+ d: Callable[SimpleParamSpec, TypeVarWithConstraints],
83
+ *e: SimpleTypeVarTuple,
84
+ ): ...
85
+ '''
86
+
87
+ expected_ast = ast.parse(source)
88
+ actual_ast = unparse(expected_ast)
89
+ compare_ast(expected_ast, ast.parse(actual_ast))