From 76b7637b7d7fd2ceabc78484108ac3fd53f22149 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 22 Jan 2023 22:43:00 +0200 Subject: [PATCH 1/3] DRAFT: Function for applying pyupgrade. Just seeing how it looks like, we would of course need to pass options in, so i'm thinking only once there is a config file; likely. So far there's just a function to call `pyupgrade` on given source code. Applying it to modified lines needs to be implemented, probably best by refactoring `_reformat_single_file()` so it can be used for different source-modifying tools. It also does use pyupgrade private internal API, and the author has explicitly stated they they were not willing to have public API beyond the CLI. We should also likely run this _before_ black; maybe even before isort ? not sure if it might remove imports... But at least it does not pass the ast unchange part. --- src/darker/__main__.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/darker/__main__.py b/src/darker/__main__.py index 8c9a38d16..e2487e0a0 100644 --- a/src/darker/__main__.py +++ b/src/darker/__main__.py @@ -370,6 +370,24 @@ def _drop_changes_on_unedited_lines( return last_successful_reformat +def pyup(content: TextDocument) -> TextDocument: + """Upgrade syntax to newer version of Python using `pyupgrade` + + :param content: The Python source code to upgrade + :return: The upgraded Python source code + + """ + + from pyupgrade._main import _fix_plugins, _fix_tokens, _fix_py36_plus, Settings + + min_version = (3, 6) + result = _fix_plugins(content.string, Settings(min_version=min_version)) + result = _fix_tokens(result, min_version) + result = _fix_py36_plus(result, min_version=min_version) + + return TextDocument(result) + + def modify_file(path: Path, new_content: TextDocument) -> None: """Write new content to a file and inform the user by logging""" logger.info("Writing %s bytes into %s", len(new_content.string), path) From 6309929632961d2364db8385d3a388afd7f8f8ac Mon Sep 17 00:00:00 2001 From: Antti Kaihola <13725+akaihola@users.noreply.github.com> Date: Sun, 22 Jan 2023 22:43:00 +0200 Subject: [PATCH 2/3] Add the `darker[pyupgrade]` extras option --- setup.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.cfg b/setup.cfg index 7b2ff8262..ee2d25c4b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,6 +51,8 @@ isort = isort>=5.0.1 color = Pygments>=2.4.0 +pyupgrade = + pyupgrade>=2.31.0 test = # NOTE: remember to keep `constraints-oldest.txt` in sync with these airium>=0.2.3 From 2195e75d3ededaa09362384e6386f21742ff86ec Mon Sep 17 00:00:00 2001 From: Antti Kaihola <13725+akaihola@users.noreply.github.com> Date: Sun, 22 Jan 2023 22:43:00 +0200 Subject: [PATCH 3/3] Move `pyupgrade` tooling to a dedicated module --- mypy.ini | 3 +++ src/darker/__main__.py | 18 ------------------ src/darker/syntax_upgrade.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 src/darker/syntax_upgrade.py diff --git a/mypy.ini b/mypy.ini index d478e24e0..e95fb7c9e 100644 --- a/mypy.ini +++ b/mypy.ini @@ -90,6 +90,9 @@ ignore_missing_imports = True [mypy-pytest.*] ignore_missing_imports = True +[mypy-pyupgrade.*] +ignore_missing_imports = True + [mypy-setuptools.*] ignore_missing_imports = True diff --git a/src/darker/__main__.py b/src/darker/__main__.py index e2487e0a0..8c9a38d16 100644 --- a/src/darker/__main__.py +++ b/src/darker/__main__.py @@ -370,24 +370,6 @@ def _drop_changes_on_unedited_lines( return last_successful_reformat -def pyup(content: TextDocument) -> TextDocument: - """Upgrade syntax to newer version of Python using `pyupgrade` - - :param content: The Python source code to upgrade - :return: The upgraded Python source code - - """ - - from pyupgrade._main import _fix_plugins, _fix_tokens, _fix_py36_plus, Settings - - min_version = (3, 6) - result = _fix_plugins(content.string, Settings(min_version=min_version)) - result = _fix_tokens(result, min_version) - result = _fix_py36_plus(result, min_version=min_version) - - return TextDocument(result) - - def modify_file(path: Path, new_content: TextDocument) -> None: """Write new content to a file and inform the user by logging""" logger.info("Writing %s bytes into %s", len(new_content.string), path) diff --git a/src/darker/syntax_upgrade.py b/src/darker/syntax_upgrade.py new file mode 100644 index 000000000..62e541fd5 --- /dev/null +++ b/src/darker/syntax_upgrade.py @@ -0,0 +1,29 @@ +"""Wrapper for applying `pyupgrade` on Python source code""" + +from darker.utils import TextDocument + +try: + from pyupgrade import _main as pyupgrade_main +except ImportError: + # `pyupgrade` is an optional dependency. Prevent the `ImportError` if it's missing. + pyupgrade_main = None + + +__all__ = ["apply_pyupgrade", "pyupgrade_main"] + + +def apply_pyupgrade(content: TextDocument) -> TextDocument: + """Upgrade syntax to newer version of Python using `pyupgrade` + + :param content: The Python source code to upgrade + :return: The upgraded Python source code + + """ + # pylint: disable=protected-access + min_version = (3, 6) + result = pyupgrade_main._fix_plugins( + content.string, pyupgrade_main.Settings(min_version=min_version) + ) + result = pyupgrade_main._fix_tokens(result, min_version) + result = pyupgrade_main._fix_py36_plus(result, min_version=min_version) + return TextDocument.from_str(result)