#!/usr/bin/env python3 """ Line Counter for Python Files - counts total lines, code lines, comment lines, and blank lines. """ import sys import ast from pathlib import Path def count_python_lines(filepath: str) -> dict: """Analyze a Python file and count line types.""" result = { "file": filepath, "total": 0, "code": 0, "comment": 0, "blank": 0 } try: with open(filepath, 'r') as f: lines = f.readlines() except Exception as e: result["error"] = str(e) return result in_docstring = False in_multiline_string = False docstring_char = None for line in lines: stripped = line.strip() result["total"] += 1 if not stripped: result["blank"] += 1 continue if stripped.startswith('#'): result["comment"] += 1 continue if stripped.startswith('"""') or stripped.startswith("'''"): if in_docstring: in_docstring = False in_multiline_string = False docstring_char = None else: in_docstring = True in_multiline_string = True docstring_char = stripped[:3] result["comment"] += 1 continue if in_docstring and docstring_char and stripped.endswith(docstring_char): in_docstring = False in_multiline_string = False result["comment"] += 1 continue if in_docstring: result["comment"] += 1 continue result["code"] += 1 return result def count_python_files(directory: str) -> dict: """Count lines for all Python files in directory.""" dir_path = Path(directory) if not dir_path.exists(): return {"error": f"Directory not found: {directory}"} totals = {"total": 0, "code": 0, "comment": 0, "blank": 0} files = [] for py_file in sorted(dir_path.glob("*.py")): result = count_python_lines(str(py_file)) files.append(result) totals["total"] += result["total"] totals["code"] += result["code"] totals["comment"] += result["comment"] totals["blank"] += result["blank"] return {"files": files, "totals": totals} if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python count_python_lines.py [file2.py] ...", file=sys.stderr) sys.exit(2) for filepath in sys.argv[1:]: result = count_python_lines(filepath) if "error" in result: print(f"ERROR: {result['error']}") else: print(f"{result['file']}: total={result['total']}, code={result['code']}, comment={result['comment']}, blank={result['blank']}")