| 1106 | }; |
| 1107 | |
| 1108 | FormatResult format_python_code_impl(const std::string& code, const PythonFormatMode mode) { |
| 1109 | if (code.empty()) |
| 1110 | return {code, "", true}; |
| 1111 | |
| 1112 | if (mode == PythonFormatMode::Strict) { |
| 1113 | const auto buffer_analysis = analyze_python_buffer(code); |
| 1114 | if (!buffer_analysis.clean()) { |
| 1115 | return {code, buffer_analysis.summary, false}; |
| 1116 | } |
| 1117 | |
| 1118 | ensure_initialized(); |
| 1119 | { |
| 1120 | const GilAcquire gil; |
| 1121 | if (const auto compile_error = compile_python_buffer_error(code); !compile_error.empty()) { |
| 1122 | return {code, compile_error, false}; |
| 1123 | } |
| 1124 | } |
| 1125 | } |
| 1126 | |
| 1127 | auto& pm = PackageManager::instance(); |
| 1128 | if (!pm.is_installed("black")) { |
| 1129 | if (!pm.ensure_venv()) { |
| 1130 | LOG_ERROR("Failed to create venv for black"); |
| 1131 | return {code, "Failed to create venv for black", false}; |
| 1132 | } |
| 1133 | LOG_INFO("Installing black..."); |
| 1134 | const auto install_result = pm.install("black"); |
| 1135 | if (!install_result.success) { |
| 1136 | LOG_ERROR("Failed to install black: {}", install_result.error); |
| 1137 | return {code, install_result.error, false}; |
| 1138 | } |
| 1139 | update_python_path(); |
| 1140 | } |
| 1141 | |
| 1142 | ensure_initialized(); |
| 1143 | const GilAcquire gil; |
| 1144 | |
| 1145 | static constexpr const char* FORMAT_CODE = R"( |
| 1146 | def _lfs_format_code(code): |
| 1147 | import importlib |
| 1148 | import re |
| 1149 | import textwrap |
| 1150 | importlib.invalidate_caches() |
| 1151 | try: |
| 1152 | import black |
| 1153 | except ImportError as e: |
| 1154 | return (None, f"ImportError: {e}") |
| 1155 | |
| 1156 | def _looks_like_code_line(stripped): |
| 1157 | if not stripped: |
| 1158 | return False |
| 1159 | if stripped.startswith('#'): |
| 1160 | return True |
| 1161 | if stripped.startswith(( |
| 1162 | 'import ', 'from ', 'def ', 'class ', '@', |
| 1163 | 'if ', 'for ', 'while ', 'try', 'with ', |
| 1164 | 'async ', 'match ', 'case ', 'return ', |
| 1165 | 'raise ', 'pass', 'break', 'continue', |
no test coverage detected