lintro 0.11.0__py3-none-any.whl → 0.13.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of lintro might be problematic. Click here for more details.

lintro/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Lintro - A unified CLI core for code formatting, linting, and quality assurance."""
2
2
 
3
- __version__ = "0.11.0"
3
+ __version__ = "0.13.0"
@@ -140,7 +140,7 @@ def format_code_legacy(
140
140
  None: This function does not return a value.
141
141
 
142
142
  Raises:
143
- Exception: If format fails for any reason.
143
+ RuntimeError: If format fails for any reason.
144
144
  """
145
145
  args: list[str] = []
146
146
  if paths:
@@ -163,5 +163,5 @@ def format_code_legacy(
163
163
  runner = CliRunner()
164
164
  result = runner.invoke(format_code, args)
165
165
  if result.exit_code != DEFAULT_EXIT_CODE:
166
- raise Exception(f"Format failed: {result.output}")
166
+ raise RuntimeError(f"Format failed: {result.output}")
167
167
  return None
@@ -94,9 +94,11 @@ def format_ruff_issues(
94
94
  non_fixable_issues: list[RuffIssue] = []
95
95
 
96
96
  for issue in issues:
97
- if isinstance(issue, RuffFormatIssue):
98
- fixable_issues.append(issue)
99
- elif isinstance(issue, RuffIssue) and issue.fixable:
97
+ if (
98
+ isinstance(issue, RuffFormatIssue)
99
+ or isinstance(issue, RuffIssue)
100
+ and issue.fixable
101
+ ):
100
102
  fixable_issues.append(issue)
101
103
  elif isinstance(issue, RuffIssue):
102
104
  non_fixable_issues.append(issue)
@@ -105,7 +107,11 @@ def format_ruff_issues(
105
107
  if format == "json":
106
108
  columns = descriptor.get_columns()
107
109
  rows = descriptor.get_rows(issues)
108
- return formatter.format(columns=columns, rows=rows, tool_name="ruff")
110
+ return formatter.format(
111
+ columns=columns,
112
+ rows=rows,
113
+ tool_name="ruff",
114
+ )
109
115
 
110
116
  sections: list[str] = []
111
117
 
@@ -36,7 +36,7 @@ def parse_prettier_output(output: str) -> list[PrettierIssue]:
36
36
 
37
37
  lines = normalized_output.splitlines()
38
38
 
39
- for i, line in enumerate(lines):
39
+ for _i, line in enumerate(lines):
40
40
  line = line.strip()
41
41
  if not line:
42
42
  continue
lintro/tools/__init__.py CHANGED
@@ -21,7 +21,7 @@ tool_manager = ToolManager()
21
21
  AVAILABLE_TOOLS = {tool_enum: tool_enum.value for tool_enum in ToolEnum}
22
22
 
23
23
 
24
- for tool_enum, tool_class in AVAILABLE_TOOLS.items():
24
+ for _tool_enum, tool_class in AVAILABLE_TOOLS.items():
25
25
  tool_manager.register_tool(tool_class)
26
26
 
27
27
  # Consolidated exports
@@ -127,6 +127,7 @@ class RuffTool(BaseTool):
127
127
  def __post_init__(self) -> None:
128
128
  """Initialize the tool with default configuration."""
129
129
  super().__post_init__()
130
+
130
131
  # Load ruff configuration from pyproject.toml
131
132
  ruff_config = _load_ruff_config()
132
133
 
@@ -151,6 +152,13 @@ class RuffTool(BaseTool):
151
152
  if "unsafe_fixes" in ruff_config:
152
153
  self.options["unsafe_fixes"] = ruff_config["unsafe_fixes"]
153
154
 
155
+ # Allow environment variable override for unsafe fixes
156
+ # Useful for development and CI environments
157
+ # This must come after config loading to override config values
158
+ env_unsafe_fixes = os.environ.get("RUFF_UNSAFE_FIXES", "").lower()
159
+ if env_unsafe_fixes in ("true", "1", "yes", "on"):
160
+ self.options["unsafe_fixes"] = True
161
+
154
162
  def set_options(
155
163
  self,
156
164
  select: list[str] | None = None,
@@ -187,14 +195,26 @@ class RuffTool(BaseTool):
187
195
  Raises:
188
196
  ValueError: If an option value is invalid.
189
197
  """
190
- if select is not None and not isinstance(select, list):
191
- raise ValueError("select must be a list of rule codes")
192
- if ignore is not None and not isinstance(ignore, list):
193
- raise ValueError("ignore must be a list of rule codes")
194
- if extend_select is not None and not isinstance(extend_select, list):
195
- raise ValueError("extend_select must be a list of rule codes")
196
- if extend_ignore is not None and not isinstance(extend_ignore, list):
197
- raise ValueError("extend_ignore must be a list of rule codes")
198
+ if select is not None:
199
+ if isinstance(select, str):
200
+ select = [select]
201
+ elif not isinstance(select, list):
202
+ raise ValueError("select must be a string or list of rule codes")
203
+ if ignore is not None:
204
+ if isinstance(ignore, str):
205
+ ignore = [ignore]
206
+ elif not isinstance(ignore, list):
207
+ raise ValueError("ignore must be a string or list of rule codes")
208
+ if extend_select is not None:
209
+ if isinstance(extend_select, str):
210
+ extend_select = [extend_select]
211
+ elif not isinstance(extend_select, list):
212
+ raise ValueError("extend_select must be a string or list of rule codes")
213
+ if extend_ignore is not None:
214
+ if isinstance(extend_ignore, str):
215
+ extend_ignore = [extend_ignore]
216
+ elif not isinstance(extend_ignore, list):
217
+ raise ValueError("extend_ignore must be a string or list of rule codes")
198
218
  if line_length is not None:
199
219
  if not isinstance(line_length, int):
200
220
  raise ValueError("line_length must be an integer")
@@ -512,9 +532,9 @@ class RuffTool(BaseTool):
512
532
  # Optionally run ruff check --fix (lint fixes)
513
533
  remaining_issues = []
514
534
  remaining_count = 0
535
+ success: bool = True # Default to True when lint_fix is disabled
515
536
  if self.options.get("lint_fix", True):
516
537
  cmd: list[str] = self._build_check_command(files=python_files, fix=True)
517
- success: bool
518
538
  output: str
519
539
  success, output = self._run_subprocess(cmd=cmd, timeout=timeout)
520
540
  remaining_issues = parse_ruff_output(output=output)
@@ -621,10 +641,7 @@ class RuffTool(BaseTool):
621
641
 
622
642
  # Success should be based on whether there are remaining issues after fixing
623
643
  # If there are no initial issues, success should be True
624
- if total_initial_count == 0:
625
- overall_success = True
626
- else:
627
- overall_success = remaining_count == 0
644
+ overall_success = True if total_initial_count == 0 else remaining_count == 0
628
645
 
629
646
  return ToolResult(
630
647
  name=self.name,
@@ -65,7 +65,7 @@ def _get_tools_to_run(
65
65
  available_names: list[str] = [e.name.lower() for e in ToolEnum]
66
66
  raise ValueError(
67
67
  f"Unknown tool '{name.lower()}'. Available tools: {available_names}",
68
- )
68
+ ) from None
69
69
 
70
70
  return tools_to_run
71
71
 
@@ -231,7 +231,7 @@ def run_lint_tools_simple(
231
231
  post_cfg_early = load_post_checks_config()
232
232
  post_enabled_early = bool(post_cfg_early.get("enabled", False))
233
233
  post_tools_early: set[str] = (
234
- set(t.lower() for t in (post_cfg_early.get("tools", []) or []))
234
+ {t.lower() for t in (post_cfg_early.get("tools", []) or [])}
235
235
  if post_enabled_early
236
236
  else set()
237
237
  )
@@ -392,10 +392,7 @@ def run_lint_tools_simple(
392
392
  if not json_output_mode:
393
393
  # Use raw output if raw_output is true, otherwise use
394
394
  # formatted output
395
- if raw_output:
396
- display_output = output
397
- else:
398
- display_output = formatted_output
395
+ display_output = output if raw_output else formatted_output
399
396
  logger.print_tool_result(
400
397
  tool_name=tool_name,
401
398
  output=display_output,
@@ -104,7 +104,7 @@ def parse_tool_list(tools_str: str | None) -> list[str]:
104
104
  try:
105
105
  result.append(ToolEnum[t.upper()])
106
106
  except KeyError:
107
- raise ValueError(f"Unknown core: {t}")
107
+ raise ValueError(f"Unknown core: {t}") from None
108
108
  return result
109
109
 
110
110
 
@@ -200,10 +200,7 @@ def get_table_columns(
200
200
  columns = expected_columns
201
201
  else:
202
202
  # Fallback: use all unique keys from the first issue
203
- if issues:
204
- columns = list(issues[0].keys())
205
- else:
206
- columns = []
203
+ columns = list(issues[0].keys()) if issues else []
207
204
 
208
205
  # Convert issues to rows
209
206
  rows: list[list[str]] = []
@@ -434,13 +431,11 @@ def walk_files_with_excludes(
434
431
  matches_pattern = True
435
432
  break
436
433
 
437
- if matches_pattern:
438
- # Check if file should be excluded
439
- if not should_exclude_path(
440
- path=rel_path,
441
- exclude_patterns=exclude_patterns,
442
- ):
443
- all_files.append(file_path)
434
+ if matches_pattern and not should_exclude_path(
435
+ path=rel_path,
436
+ exclude_patterns=exclude_patterns,
437
+ ):
438
+ all_files.append(file_path)
444
439
 
445
440
  return sorted(all_files)
446
441
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lintro
3
- Version: 0.11.0
3
+ Version: 0.13.0
4
4
  Summary: A unified CLI tool for code formatting, linting, and quality assurance
5
5
  Author-email: TurboCoder13 <turbocoder13@gmail.com>
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- lintro/__init__.py,sha256=easVN8Os0LdRM2aNOtZOTWIIIED2qxFQe5N-yGSdMl8,111
1
+ lintro/__init__.py,sha256=WiKLj8c7w8DfMAIV99LDnB0b9k-fDbpYJfHr2Va6wZM,111
2
2
  lintro/__main__.py,sha256=McxM6wEcEeCLBHZs0F8xzT1PxVqJYkjtaPq1_-Nug-0,106
3
3
  lintro/cli.py,sha256=0apxBcqVxBZdCeXGMyaSdJYSntMIiCFwPwan1jUmPzM,2520
4
4
  lintro/ascii-art/fail.txt,sha256=gshKngSrz5FvJdP6g7lPygpLsLsZZh4etBU_wR7PXOw,56396
@@ -6,7 +6,7 @@ lintro/ascii-art/success.txt,sha256=xhteIXcBvl_1QcFKMIS9CkjjCY8czdf9znP9AiB8oPU,
6
6
  lintro/cli_utils/__init__.py,sha256=F5P_fY_s-gwNZrnV1bzUOgHGb73QeZG1i-K_kfyJ8Yg,250
7
7
  lintro/cli_utils/commands/__init__.py,sha256=GGT-uG0gQLlHAqkrwfwqfCkD6DUMP4Tq1rgDgaYe5Ng,239
8
8
  lintro/cli_utils/commands/check.py,sha256=YnpuiX8-kTADnwxS_mZUPf_SkmqdyqTZFJLTDf7QSQ8,6229
9
- lintro/cli_utils/commands/format.py,sha256=nEU0Hv28O0RCIp6l-pFcKSzzyLE6fajQCiUYpRyHfzU,5175
9
+ lintro/cli_utils/commands/format.py,sha256=scRuwm2xUzz0AA6QECJRrX8GX1L7fZfX8FGq-7cycTo,5181
10
10
  lintro/cli_utils/commands/list_tools.py,sha256=zGs5m3Dehk6HhS5WbBGTe_-GFrE-OsaAFQLZcm0MwMw,3495
11
11
  lintro/enums/__init__.py,sha256=ZwCDematwfGNPdZJN9j-yoGE5SkkoddRhoHz3F9pLMY,61
12
12
  lintro/enums/action.py,sha256=3gln8HUNpZzAyAAjQH-cOyW1nKCx9MT6S4rFDAVirdc,597
@@ -37,7 +37,7 @@ lintro/formatters/tools/black_formatter.py,sha256=YTe0Zc82p8cWwlq03bRaSJKOT8iHqX
37
37
  lintro/formatters/tools/darglint_formatter.py,sha256=owYIP3QxtTantBwfd4w1GVfaRiaHFXSynxAntSKw7IU,2649
38
38
  lintro/formatters/tools/hadolint_formatter.py,sha256=OWc2BYae31U2TdNcxXkGl0W6fTjVWkkaJV57X4l4jRw,2995
39
39
  lintro/formatters/tools/prettier_formatter.py,sha256=GYAyHppot5aG_pWF8QHz5GmWqmqgZwE6UmcUQZFesWE,2915
40
- lintro/formatters/tools/ruff_formatter.py,sha256=DzH-gs-3IhUFQ6cT6rgVxW1RVNVkGo2jrrEZ4Kx-MS8,4445
40
+ lintro/formatters/tools/ruff_formatter.py,sha256=i3jDrEQ_8bP_AhRAgaXYSp4eVCQnjapURugWFNZCmzg,4488
41
41
  lintro/formatters/tools/yamllint_formatter.py,sha256=oEwkU-I4Upfc8--KAgfVAPSyYbeqkdsDXucxj3OwjIA,3093
42
42
  lintro/models/__init__.py,sha256=E6tU5BnnaRWyMEf2cdiN_C3nvbRlWDfblKHrK0is7IU,73
43
43
  lintro/models/core/__init__.py,sha256=mevoEG547VTotUsgyocEB72OknnGhExNWcfel7ZPLnI,54
@@ -58,14 +58,14 @@ lintro/parsers/hadolint/hadolint_issue.py,sha256=VlTzTPHcluFZihFL-Tkg7UuXp1fQcD0
58
58
  lintro/parsers/hadolint/hadolint_parser.py,sha256=Q7Hf6sL45s38O3C9dbBYzOpDlb0KGFj0U3Yry_ixdK8,1810
59
59
  lintro/parsers/prettier/__init__.py,sha256=jH8yEsh_X6TpwJs1V1cN1AmbDuQwQ9qWA-_dk0R9jOA,55
60
60
  lintro/parsers/prettier/prettier_issue.py,sha256=DKxV9LXxAB-CxvOsbWVEAmfpXQJvd4ikHKGyMrg1Y60,569
61
- lintro/parsers/prettier/prettier_parser.py,sha256=lH50rhFHbWWLH50CiTlyIvjgbx9vz1hiIdtxEXi7uJw,2043
61
+ lintro/parsers/prettier/prettier_parser.py,sha256=TDD0KRF3NMUL24Qjo4TwSOklkwZT-KmwRbTWKTJt434,2044
62
62
  lintro/parsers/ruff/__init__.py,sha256=1oT00c82qKfveRqa4FnSedAEQjQVrb9BspJEUQJn-Kk,26
63
63
  lintro/parsers/ruff/ruff_issue.py,sha256=96ht6YWImOBiRTo0ATlM1PvVhgIwFiuN8810emm9nXo,1142
64
64
  lintro/parsers/ruff/ruff_parser.py,sha256=DRGzpf55OnNJCTO01RSFK4GXr6Lav-_JzACdqDesuj0,4722
65
65
  lintro/parsers/yamllint/__init__.py,sha256=ZZtw7Ref1EAbY-IwSz2UxJauGak6sKO10pfYsdE_sV8,55
66
66
  lintro/parsers/yamllint/yamllint_issue.py,sha256=jWawdGUiTI1HADbhg8yEdZfC6yHcmk9FDzpr3PBUPBg,608
67
67
  lintro/parsers/yamllint/yamllint_parser.py,sha256=ol44xhJcspnGIsEta8vVv1xi-sIbpB12CovmT94QFmQ,1947
68
- lintro/tools/__init__.py,sha256=S-L_x7Hzp-Ja-QezupEUwF6-uhRl4ZXSIpRx59jvsaA,1410
68
+ lintro/tools/__init__.py,sha256=7uVo7qfdr9I_OOdF--0l16Gip6XhAG1QxPsuEWgHMko,1411
69
69
  lintro/tools/tool_enum.py,sha256=RkJcfEpM_lFWp2y1rFqZdr3qOzYVcSoVBt3XVbtO4Sg,926
70
70
  lintro/tools/core/__init__.py,sha256=eUbc-DlpOcFaG_gKzy-veaOQAOkC5-OuItxI--p6I9c,59
71
71
  lintro/tools/core/tool_base.py,sha256=yOEvReleksIV_t_aB4PZv6-PgXZTrHTnz4SDPSr_MSk,13480
@@ -77,7 +77,7 @@ lintro/tools/implementations/tool_black.py,sha256=x1U6NhdRxxYE5Tmvh-LoxcWtIkwHce
77
77
  lintro/tools/implementations/tool_darglint.py,sha256=1G_gxjhkFNNCVCSkMDAgicYEZJ6JcI_NGX47Sg3a1vM,9561
78
78
  lintro/tools/implementations/tool_hadolint.py,sha256=NfHLoThp23V-n5chSfrBZetleXsRR4oYxkLxOkJxU0g,11479
79
79
  lintro/tools/implementations/tool_prettier.py,sha256=tTw3yEn6RR2rCBoZdeDWy6r06Sfd_jCR2fLCBj4MDoY,9783
80
- lintro/tools/implementations/tool_ruff.py,sha256=YkVwvbBE-yxzcufnk8bnewBOfHqGsbzVsrKYEUX3mkQ,25356
80
+ lintro/tools/implementations/tool_ruff.py,sha256=v6ROLphXuX90sd_AXuQcn3z-8PqCmYXPkbxMlAZcbaw,26174
81
81
  lintro/tools/implementations/tool_yamllint.py,sha256=0powR9F3FkIq-b7PI0-XWdh7nx7rR3HVMtvEaz_NWeA,8831
82
82
  lintro/utils/__init__.py,sha256=mUAkJXnTb91theOR_ue6FfGHtuSm3C466T_SH_KoWRE,70
83
83
  lintro/utils/ascii_normalize_cli.py,sha256=Rlasrsy9FShCKGJ_9ti4VxJGP-I05vAtTmNMENbo_a4,2575
@@ -86,11 +86,11 @@ lintro/utils/console_logger.py,sha256=N0n5LomG6MDqu4tSPbmhBsIB6lzpRl5M53tZx6EoF4
86
86
  lintro/utils/formatting.py,sha256=khC9hYBva5xqBV1IqNcivRH9gRdvWw6u6mh2TZLTy7E,5346
87
87
  lintro/utils/output_manager.py,sha256=oIE0g8LNVQcWSQOb1MbDVqGYPrOjBGuUZ4R80M1RevQ,10213
88
88
  lintro/utils/path_utils.py,sha256=NJP3vjVDcRBgUHtYNrpL0tRa0Sc3oQhGX3_2WWzdZE4,1395
89
- lintro/utils/tool_executor.py,sha256=8-m7nQKLRlKHBTvzT7iLmaHYZ3-2s0t4zUbC-py8-H8,26204
90
- lintro/utils/tool_utils.py,sha256=DIdebZxdUBhomuBKSezfojNOmEZyP7KtGifz1EX1qZo,15746
91
- lintro-0.11.0.dist-info/licenses/LICENSE,sha256=CwaAnyD2psonDBBJjbqFUz00W8nQw-FGDlEGZReUV6A,1069
92
- lintro-0.11.0.dist-info/METADATA,sha256=4srNVKdH1uEE1q0a_pvTqVMi3h7CiwWE2Yl-LSgDvtU,16030
93
- lintro-0.11.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
94
- lintro-0.11.0.dist-info/entry_points.txt,sha256=SYSk35jFyNLEHyrofSJsRv4qFN9NsT4VWSbvnTS9ov0,43
95
- lintro-0.11.0.dist-info/top_level.txt,sha256=_D-7eyV6gNBOoIwHuf_h60wN_RWiw8GxB430Il9VKhU,7
96
- lintro-0.11.0.dist-info/RECORD,,
89
+ lintro/utils/tool_executor.py,sha256=PNUuWkQj4TWI9UHVvZUpWoDkU00MAd1o5_VhG-iviCo,26124
90
+ lintro/utils/tool_utils.py,sha256=T3A5xf4zokUMPVzWzEn3f0M14EcDxoeRo-jf5yXEoyI,15613
91
+ lintro-0.13.0.dist-info/licenses/LICENSE,sha256=CwaAnyD2psonDBBJjbqFUz00W8nQw-FGDlEGZReUV6A,1069
92
+ lintro-0.13.0.dist-info/METADATA,sha256=7cH3EBX-jrE9CFO1h63epWySmOAfUcxh9taqeZKo3Xw,16030
93
+ lintro-0.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
94
+ lintro-0.13.0.dist-info/entry_points.txt,sha256=SYSk35jFyNLEHyrofSJsRv4qFN9NsT4VWSbvnTS9ov0,43
95
+ lintro-0.13.0.dist-info/top_level.txt,sha256=_D-7eyV6gNBOoIwHuf_h60wN_RWiw8GxB430Il9VKhU,7
96
+ lintro-0.13.0.dist-info/RECORD,,