]> git.madduck.net Git - etc/vim.git/commitdiff

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Allow install under pypy (#2559)
authorOliver Margetts <oliver.margetts@gmail.com>
Sun, 14 Nov 2021 03:46:15 +0000 (03:46 +0000)
committerGitHub <noreply@github.com>
Sun, 14 Nov 2021 03:46:15 +0000 (19:46 -0800)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Richard Si <63936253+ichard26@users.noreply.github.com>
.github/workflows/test.yml
CHANGES.md
docs/faq.md
setup.py
src/black/cache.py
src/black/parsing.py
tests/test_black.py
tox.ini

index 296ac34a3fba34e85aac4915c20e09b1600d7702..7ba2a84d049b301215088e3fa869a4997ba5ccbf 100644 (file)
@@ -24,7 +24,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
+        python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "pypy-3.7"]
         os: [ubuntu-latest, macOS-latest, windows-latest]
 
     steps:
         os: [ubuntu-latest, macOS-latest, windows-latest]
 
     steps:
@@ -41,9 +41,15 @@ jobs:
           python -m pip install --upgrade tox
 
       - name: Unit tests
           python -m pip install --upgrade tox
 
       - name: Unit tests
+        if: "!startsWith(matrix.python-version, 'pypy')"
         run: |
           tox -e ci-py -- -v --color=yes
 
         run: |
           tox -e ci-py -- -v --color=yes
 
+      - name: Unit tests pypy
+        if: "startsWith(matrix.python-version, 'pypy')"
+        run: |
+          tox -e ci-pypy3 -- -v --color=yes
+
       - name: Publish coverage to Coveralls
         # If pushed / is a pull request against main repo AND
         # we're running on Linux (this action only supports Linux)
       - name: Publish coverage to Coveralls
         # If pushed / is a pull request against main repo AND
         # we're running on Linux (this action only supports Linux)
index b2e8f7439b7eba99ed711128f319e34bfbd41f8c..c8b9c8498156b8e5a3dd06d01a9d5abaa5d9f771 100644 (file)
@@ -6,6 +6,7 @@
 
 - Warn about Python 2 deprecation in more cases by improving Python 2 only syntax
   detection (#2592)
 
 - Warn about Python 2 deprecation in more cases by improving Python 2 only syntax
   detection (#2592)
+- Add experimental PyPy support (#2559)
 - Add partial support for the match statement. As it's experimental, it's only enabled
   when `--target-version py310` is explicitly specified (#2586)
 - Add support for parenthesized with (#2586)
 - Add partial support for the match statement. As it's experimental, it's only enabled
   when `--target-version py310` is explicitly specified (#2586)
 - Add support for parenthesized with (#2586)
index 77f9df51fd4ad1413e2c160f8b9cafb70a7c4f8e..72bae6b389df003c70647599d14d83616fb74bde 100644 (file)
@@ -92,3 +92,8 @@ influence their behavior. While Black does its best to recognize such comments a
 them in the right place, this detection is not and cannot be perfect. Therefore, you'll
 sometimes have to manually move these comments to the right place after you format your
 codebase with _Black_.
 them in the right place, this detection is not and cannot be perfect. Therefore, you'll
 sometimes have to manually move these comments to the right place after you format your
 codebase with _Black_.
+
+## Can I run black with PyPy?
+
+Yes, there is support for PyPy 3.7 and higher. You cannot format Python 2 files under
+PyPy, because PyPy's inbuilt ast module does not support this.
index de84dc37bb8af7869203eff1b38f68b6fb0d7a07..a0c2006ef33792800ae09758f834516246710872 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -75,7 +75,7 @@ setup(
         "click>=7.1.2",
         "platformdirs>=2",
         "tomli>=0.2.6,<2.0.0",
         "click>=7.1.2",
         "platformdirs>=2",
         "tomli>=0.2.6,<2.0.0",
-        "typed-ast>=1.4.2; python_version < '3.8'",
+        "typed-ast>=1.4.2; python_version < '3.8' and implementation_name == 'cpython'",
         "regex>=2020.1.8",
         "pathspec>=0.9.0, <1",
         "dataclasses>=0.6; python_version < '3.7'",
         "regex>=2020.1.8",
         "pathspec>=0.9.0, <1",
         "dataclasses>=0.6; python_version < '3.7'",
index 3f165de2ed60bf2563cee4e662baeb36c3553a40..bca7279f990bd222259fa9d362c1c18a60b38075 100644 (file)
@@ -35,7 +35,7 @@ def read_cache(mode: Mode) -> Cache:
     with cache_file.open("rb") as fobj:
         try:
             cache: Cache = pickle.load(fobj)
     with cache_file.open("rb") as fobj:
         try:
             cache: Cache = pickle.load(fobj)
-        except (pickle.UnpicklingError, ValueError):
+        except (pickle.UnpicklingError, ValueError, IndexError):
             return {}
 
     return cache
             return {}
 
     return cache
index fc540ad021dc240547d332a70dd91ffee256a2cc..ee6aae1e7ff9db26be2f5f4c439a25d31baf2b7d 100644 (file)
@@ -2,6 +2,7 @@
 Parse Python code and perform AST validation.
 """
 import ast
 Parse Python code and perform AST validation.
 """
 import ast
+import platform
 import sys
 from typing import Iterable, Iterator, List, Set, Union, Tuple
 
 import sys
 from typing import Iterable, Iterator, List, Set, Union, Tuple
 
@@ -15,10 +16,13 @@ from blib2to3.pgen2.parse import ParseError
 from black.mode import TargetVersion, Feature, supports_feature
 from black.nodes import syms
 
 from black.mode import TargetVersion, Feature, supports_feature
 from black.nodes import syms
 
+_IS_PYPY = platform.python_implementation() == "PyPy"
+
 try:
     from typed_ast import ast3, ast27
 except ImportError:
 try:
     from typed_ast import ast3, ast27
 except ImportError:
-    if sys.version_info < (3, 8):
+    # Either our python version is too low, or we're on pypy
+    if sys.version_info < (3, 7) or (sys.version_info < (3, 8) and not _IS_PYPY):
         print(
             "The typed_ast package is required but not installed.\n"
             "You can upgrade to Python 3.8+ or install typed_ast with\n"
         print(
             "The typed_ast package is required but not installed.\n"
             "You can upgrade to Python 3.8+ or install typed_ast with\n"
@@ -117,7 +121,10 @@ def parse_single_version(
     if sys.version_info >= (3, 8) and version >= (3,):
         return ast.parse(src, filename, feature_version=version)
     elif version >= (3,):
     if sys.version_info >= (3, 8) and version >= (3,):
         return ast.parse(src, filename, feature_version=version)
     elif version >= (3,):
-        return ast3.parse(src, filename, feature_version=version[1])
+        if _IS_PYPY:
+            return ast3.parse(src, filename)
+        else:
+            return ast3.parse(src, filename, feature_version=version[1])
     elif version == (2, 7):
         return ast27.parse(src)
     raise AssertionError("INTERNAL ERROR: Tried parsing unsupported Python version!")
     elif version == (2, 7):
         return ast27.parse(src)
     raise AssertionError("INTERNAL ERROR: Tried parsing unsupported Python version!")
@@ -151,12 +158,14 @@ def stringify_ast(
     yield f"{'  ' * depth}{node.__class__.__name__}("
 
     for field in sorted(node._fields):  # noqa: F402
     yield f"{'  ' * depth}{node.__class__.__name__}("
 
     for field in sorted(node._fields):  # noqa: F402
-        # TypeIgnore has only one field 'lineno' which breaks this comparison
-        type_ignore_classes = (ast3.TypeIgnore, ast27.TypeIgnore)
-        if sys.version_info >= (3, 8):
-            type_ignore_classes += (ast.TypeIgnore,)
-        if isinstance(node, type_ignore_classes):
-            break
+        # TypeIgnore will not be present using pypy < 3.8, so need for this
+        if not (_IS_PYPY and sys.version_info < (3, 8)):
+            # TypeIgnore has only one field 'lineno' which breaks this comparison
+            type_ignore_classes = (ast3.TypeIgnore, ast27.TypeIgnore)
+            if sys.version_info >= (3, 8):
+                type_ignore_classes += (ast.TypeIgnore,)
+            if isinstance(node, type_ignore_classes):
+                break
 
         try:
             value = getattr(node, field)
 
         try:
             value = getattr(node, field)
index 7dbc3809d26c0bd53523202224ee6b7037df63a5..301a3a5b3637a3b2a0c43031b43269e238bfa72e 100644 (file)
@@ -944,7 +944,7 @@ class BlackTestCase(BlackBaseTestCase):
             symlink = workspace / "broken_link.py"
             try:
                 symlink.symlink_to("nonexistent.py")
             symlink = workspace / "broken_link.py"
             try:
                 symlink.symlink_to("nonexistent.py")
-            except OSError as e:
+            except (OSError, NotImplementedError) as e:
                 self.skipTest(f"Can't create symlinks: {e}")
             self.invokeBlack([str(workspace.resolve())])
 
                 self.skipTest(f"Can't create symlinks: {e}")
             self.invokeBlack([str(workspace.resolve())])
 
diff --git a/tox.ini b/tox.ini
index 57f41acb3d17a04845dc69c336339f21d3640e2d..683a5439ea98e755b27b42cf0bfeda28bac13ab2 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
 [tox]
-envlist = {,ci-}py{36,37,38,39,310},fuzz
+envlist = {,ci-}py{36,37,38,39,310,py3},fuzz
 
 [testenv]
 setenv = PYTHONPATH = {toxinidir}/src
 
 [testenv]
 setenv = PYTHONPATH = {toxinidir}/src
@@ -31,6 +31,31 @@ commands =
         --cov --cov-append {posargs}
     coverage report
 
         --cov --cov-append {posargs}
     coverage report
 
+[testenv:{,ci-}pypy3]
+setenv = PYTHONPATH = {toxinidir}/src
+skip_install = True
+recreate = True
+deps =
+    -r{toxinidir}/test_requirements.txt
+; a separate worker is required in ci due to https://foss.heptapod.net/pypy/pypy/-/issues/3317
+; this seems to cause tox to wait forever
+; remove this when pypy releases the bugfix
+commands =
+    pip install -e .[d]
+    coverage erase
+    pytest tests --run-optional no_python2 \
+        --run-optional no_jupyter \
+        !ci: --numprocesses auto \
+        ci: --numprocesses 1 \
+        --cov {posargs}
+    pip install -e .[jupyter]
+    pytest tests --run-optional jupyter \
+        -m jupyter \
+        !ci: --numprocesses auto \
+        ci: --numprocesses 1 \
+        --cov --cov-append {posargs}
+    coverage report
+
 [testenv:fuzz]
 skip_install = True
 deps =
 [testenv:fuzz]
 skip_install = True
 deps =