11
11
from pathlib import Path
12
12
from typing import Any , NamedTuple
13
13
14
+ import black
14
15
import isort
15
- from ufmt .core import ufmt_string
16
- from ufmt .util import make_black_config
17
- from usort import Config as UsortConfig
16
+ import usort
18
17
19
18
20
19
IS_WINDOWS : bool = os .name == "nt"
@@ -53,7 +52,7 @@ def format_error_message(filename: str, err: Exception) -> LintMessage:
53
52
path = filename ,
54
53
line = None ,
55
54
char = None ,
56
- code = "UFMT " ,
55
+ code = "PYFMT " ,
57
56
severity = LintSeverity .ADVICE ,
58
57
name = "command-failed" ,
59
58
original = None ,
@@ -62,39 +61,53 @@ def format_error_message(filename: str, err: Exception) -> LintMessage:
62
61
)
63
62
64
63
64
+ def run_isort (content : str , path : Path ) -> str :
65
+ isort_config = isort .Config (settings_path = str (REPO_ROOT ))
66
+
67
+ is_this_file = path .samefile (__file__ )
68
+ if not is_this_file :
69
+ content = re .sub (r"(#.*\b)usort:\s*skip\b" , r"\g<1>isort: split" , content )
70
+
71
+ content = isort .code (content , config = isort_config , file_path = path )
72
+
73
+ if not is_this_file :
74
+ content = re .sub (r"(#.*\b)isort: split\b" , r"\g<1>usort: skip" , content )
75
+
76
+ return content
77
+
78
+
79
+ def run_usort (content : str , path : Path ) -> str :
80
+ usort_config = usort .Config .find (path )
81
+
82
+ return usort .usort_string (content , path = path , config = usort_config )
83
+
84
+
85
+ def run_black (content : str , path : Path ) -> str :
86
+ black_config = black .parse_pyproject_toml (black .find_pyproject_toml ((str (path ),))) # type: ignore[attr-defined,arg-type]
87
+ # manually patch options that do not have a 1-to-1 match in Mode arguments
88
+ black_config ["target_versions" ] = {
89
+ black .TargetVersion [ver .upper ()] # type: ignore[attr-defined]
90
+ for ver in black_config .pop ("target_version" , [])
91
+ }
92
+ black_config ["string_normalization" ] = not black_config .pop (
93
+ "skip_string_normalization" , False
94
+ )
95
+ black_mode = black .Mode (** black_config )
96
+ black_mode .is_pyi = path .suffix .lower () == ".pyi"
97
+ black_mode .is_ipynb = path .suffix .lower () == ".ipynb"
98
+
99
+ return black .format_str (content , mode = black_mode )
100
+
101
+
65
102
def check_file (filename : str ) -> list [LintMessage ]:
66
103
path = Path (filename ).absolute ()
67
- original = path .read_text (encoding = "utf-8" )
104
+ original = replacement = path .read_text (encoding = "utf-8" )
68
105
69
106
try :
70
- isort_config = isort .Config (settings_path = str (REPO_ROOT ))
71
- usort_config = UsortConfig .find (path )
72
- black_config = make_black_config (path )
73
-
74
- if not path .samefile (__file__ ):
75
- isorted_replacement = re .sub (
76
- r"(#.*\b)isort: split\b" ,
77
- r"\g<1>usort: skip" ,
78
- isort .code (
79
- re .sub (r"(#.*\b)usort:\s*skip\b" , r"\g<1>isort: split" , original ),
80
- config = isort_config ,
81
- file_path = path ,
82
- ),
83
- )
84
- else :
85
- isorted_replacement = isort .code (
86
- original ,
87
- config = isort_config ,
88
- file_path = path ,
89
- )
90
-
91
- # Use UFMT API to call both usort and black
92
- replacement = ufmt_string (
93
- path = path ,
94
- content = isorted_replacement ,
95
- usort_config = usort_config ,
96
- black_config = black_config ,
97
- )
107
+ # NB: run isort first to enforce style for blank lines
108
+ replacement = run_isort (replacement , path = path )
109
+ replacement = run_usort (replacement , path = path )
110
+ replacement = run_black (replacement , path = path )
98
111
99
112
if original == replacement :
100
113
return []
@@ -104,7 +117,7 @@ def check_file(filename: str) -> list[LintMessage]:
104
117
path = filename ,
105
118
line = None ,
106
119
char = None ,
107
- code = "UFMT " ,
120
+ code = "PYFMT " ,
108
121
severity = LintSeverity .WARNING ,
109
122
name = "format" ,
110
123
original = original ,
@@ -118,7 +131,7 @@ def check_file(filename: str) -> list[LintMessage]:
118
131
119
132
def main () -> None :
120
133
parser = argparse .ArgumentParser (
121
- description = "Format files with ufmt (black + usort) ." ,
134
+ description = "Format files with usort + black ." ,
122
135
fromfile_prefix_chars = "@" ,
123
136
)
124
137
parser .add_argument (
0 commit comments