11"""Helpers for invoking ``isort`` and acting on its output"""
22
33import logging
4+ from contextlib import suppress
45from pathlib import Path
56from typing import Any , Collection , List , Optional , TypedDict
67
@@ -51,9 +52,10 @@ class IsortArgs(TypedDict, total=False):
5152 settings_path : str
5253
5354
54- def apply_isort ( # pylint: disable=too-many-arguments
55+ def apply_isort ( # pylint: disable=too-many-arguments # noqa: PLR0913
5556 content : TextDocument ,
56- src : Path ,
57+ relative_path : Path ,
58+ root : Path ,
5759 exclude : Collection [str ],
5860 edited_linenums_differ : EditedLinenumsDiffer ,
5961 config : Optional [str ] = None ,
@@ -62,27 +64,28 @@ def apply_isort( # pylint: disable=too-many-arguments
6264 """Run isort on the given Python source file content
6365
6466 :param content: The contents of the Python source code file to sort imports in
65- :param src: The relative path to the file. This must be the actual path in the
66- repository, which may differ from the path given on the command line in
67- case of VSCode temporary files.
67+ :param relative_path: The path to the file relative to ``root``. Note that this may
68+ differ from the path given on the command line in case of
69+ VSCode temporary files.
70+ :param root: The root directory based on which ``src`` is resolved.
6871 :param exclude: The file path patterns to exclude from import sorting
6972 :param edited_linenums_differ: Helper for finding out which lines were edited
7073 :param config: Path to configuration file
7174 :param line_length: Maximum line length to use
7275 :return: Original Python source file contents with imports sorted
7376
7477 """
75- if glob_any (src , exclude ):
78+ if glob_any (relative_path , exclude ):
7679 return content
7780 edited_linenums = edited_linenums_differ .revision_vs_lines (
78- src ,
81+ relative_path ,
7982 content ,
8083 context_lines = 0 ,
8184 ) # pylint: disable=duplicate-code
8285 if not edited_linenums :
8386 return content
84- isort_args = _build_isort_args (src , config , line_length )
85- rev2_isorted = _call_isort_code (content , isort_args )
87+ isort_args = _build_isort_args (root / relative_path , config , line_length )
88+ rev2_isorted = _call_isort_code (content , root / relative_path , isort_args )
8689 # Get the chunks in the diff between the edited and import-sorted file
8790 isort_chunks = diff_chunks (content , rev2_isorted )
8891 if not isort_chunks :
@@ -98,15 +101,16 @@ def apply_isort( # pylint: disable=too-many-arguments
98101
99102
100103def _build_isort_args (
101- src : Path ,
104+ path_from_cwd : Path ,
102105 config : Optional [str ] = None ,
103106 line_length : Optional [int ] = None ,
104107) -> IsortArgs :
105108 """Build ``isort.code()`` keyword arguments
106109
107- :param src: The relative path to the file. This must be the actual path in the
108- repository, which may differ from the path given on the command line in
109- case of VSCode temporary files.
110+ :param path_from_cwd: The path to the file. This must be either an absolute path or
111+ a relative path from the current working directory. Note that
112+ this may differ from the path given on the command line in
113+ case of VSCode temporary files.
110114 :param config: Path to configuration file
111115 :param line_length: Maximum line length to use
112116
@@ -115,16 +119,20 @@ def _build_isort_args(
115119 if config :
116120 isort_args ["settings_file" ] = config
117121 else :
118- isort_args ["settings_path" ] = str (find_project_root ((str (src ),)))
122+ isort_args ["settings_path" ] = str (find_project_root ((str (path_from_cwd ),)))
119123 if line_length :
120124 isort_args ["line_length" ] = line_length
121125 return isort_args
122126
123127
124- def _call_isort_code (content : TextDocument , isort_args : IsortArgs ) -> TextDocument :
128+ def _call_isort_code (
129+ content : TextDocument , path_from_cwd : Path , isort_args : IsortArgs
130+ ) -> TextDocument :
125131 """Call ``isort.code()`` and return the result as a `TextDocument` object
126132
127133 :param content: The contents of the Python source code file to sort imports in
134+ :param path_from_cwd: The path to the file with the given content, either relative
135+ to the current working directory or an absolute path.
128136 :param isort_args: Keyword arguments for ``isort.code()``
129137
130138 """
@@ -133,10 +141,8 @@ def _call_isort_code(content: TextDocument, isort_args: IsortArgs) -> TextDocume
133141 "isort.code(code=..., %s)" ,
134142 ", " .join (f"{ k } ={ v !r} " for k , v in isort_args .items ()),
135143 )
136- try :
137- code = isort_code (code = code , ** isort_args )
138- except isort .exceptions .FileSkipComment :
139- pass
144+ with suppress (isort .exceptions .FileSkipped ):
145+ code = isort_code (code = code , file_path = path_from_cwd , ** isort_args )
140146 return TextDocument .from_str (
141147 code ,
142148 encoding = content .encoding ,
0 commit comments