Allow install under pypy (#2559)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com> Co-authored-by: Richard Si <63936253+ichard26@users.noreply.github.com>
This commit is contained in:
parent
1e0ec543ff
commit
eb9d0396cd
8
.github/workflows/test.yml
vendored
8
.github/workflows/test.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
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:
|
||||
@ -41,9 +41,15 @@ jobs:
|
||||
python -m pip install --upgrade tox
|
||||
|
||||
- name: Unit tests
|
||||
if: "!startsWith(matrix.python-version, 'pypy')"
|
||||
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)
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
- 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)
|
||||
|
@ -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_.
|
||||
|
||||
## 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.
|
||||
|
2
setup.py
2
setup.py
@ -75,7 +75,7 @@ def get_long_description() -> str:
|
||||
"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'",
|
||||
|
@ -35,7 +35,7 @@ def read_cache(mode: Mode) -> Cache:
|
||||
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
|
||||
|
@ -2,6 +2,7 @@
|
||||
Parse Python code and perform AST validation.
|
||||
"""
|
||||
import ast
|
||||
import platform
|
||||
import sys
|
||||
from typing import Iterable, Iterator, List, Set, Union, Tuple
|
||||
|
||||
@ -15,10 +16,13 @@
|
||||
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:
|
||||
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"
|
||||
@ -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,):
|
||||
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!")
|
||||
@ -151,12 +158,14 @@ def stringify_ast(
|
||||
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)
|
||||
|
@ -944,7 +944,7 @@ def test_broken_symlink(self) -> None:
|
||||
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())])
|
||||
|
||||
|
27
tox.ini
27
tox.ini
@ -1,5 +1,5 @@
|
||||
[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
|
||||
@ -31,6 +31,31 @@ commands =
|
||||
--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 =
|
||||
|
Loading…
Reference in New Issue
Block a user