1 पॉइंट द्वारा GN⁺ 1 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Rust में लिखा गया Python linter·formatter Ruff v0.16.0 डिफ़ॉल्ट रूप से सक्रिय नियमों की संख्या 59 से बढ़ाकर 413 कर देता है, जिससे बिना अलग कॉन्फ़िगरेशन के syntax errors और तुरंत होने वाली runtime errors को अधिक व्यापक रूप से पकड़ा जा सकता है
  • Markdown में python, py, pyi, pycon आदि से चिह्नित Python code block formatting का समर्थन करता है और इसे Quarto notebooks पर भी लागू किया जा सकता है
  • ruff: ignore और ruff: file-ignore जोड़े गए हैं, जिनसे logical code line या पूरी file के diagnostics को दबाया जा सकता है, और --add-ignore से comments अपने-आप डाले जा सकते हैं
  • check और format --check संशोधनों को डिफ़ॉल्ट diagnostics के नीचे diff के रूप में दिखाते हैं, और formatter check अब JSON तथा GitHub·GitLab CI comments के लिए output formats भी सपोर्ट करता है
  • ज़्यादातर मामलों में बड़े बदलाव के बिना upgrade किया जा सकता है, लेकिन बढ़े हुए डिफ़ॉल्ट नियमों और कुछ values के null हो सकने वाले JSON output changes का मौजूदा settings और automation tools पर असर ज़रूर जाँचना चाहिए

डिफ़ॉल्ट नियम 413 तक विस्तारित

  • Ruff v0.16.0 Rust में लिखा गया एक तेज़ Python linter·formatter है, जिसे PyPI या uv tool install ruff@latest से install किया जा सकता है
  • Ruff के कुल नियम v0.1.0 के समय 708 से बढ़कर 968 हो चुके हैं, लेकिन डिफ़ॉल्ट रूप से सक्रिय नियम अब तक 59 ही बने हुए थे
  • v0.16 डिफ़ॉल्ट नियमों को 413 तक बढ़ाता है, जिससे syntax errors और तुरंत होने वाली runtime errors सहित गंभीर समस्याएँ बिना अलग कॉन्फ़िगरेशन के पकड़ी जा सकती हैं
    • इसमें flake8-bugbear के B, pyupgrade के UP, और Ruff के अपने RUF category rules शामिल हैं
    • पूरी सूची Default Rules दस्तावेज़ में देखी जा सकती है
  • जो projects पहले से select या extend-select का उपयोग करते हैं, वे भी इन नए डिफ़ॉल्ट नियमों के ज़रिए पहले अनदेखे उपयोगी नियमों को देख सकते हैं
  • पुराने डिफ़ॉल्ट नियमों पर लौटने के लिए इस तरह सेट करें
[lint]
select = ["E4", "E7", "E9", "F"]
  • यह बदलाव लंबे समय से चल रहे rule reclassification कार्य से जुड़ा है, और इससे संबंधित काम आगे भी जारी रहेगा

Markdown code block formatting

  • ruff format Markdown files में शामिल Python fenced code blocks को format करता है
  • समर्थित info strings हैं: python, py, python3, py3, pyi, pycon
    • pyi को stub file format की तरह माना जाता है
    • pycon को REPL session format की तरह माना जाता है
    • बाकी को सामान्य Python files की तरह format किया जाता है
  • अगर language name {python} की तरह curly braces में घिरा हो तब भी उसे पहचाना जाता है, इसलिए इसे Quarto notebooks में भी इस्तेमाल किया जा सकता है
    • अगर .qmd extension इस्तेमाल हो रही है, तो extension mapping setting की ज़रूरत पड़ सकती है
  • code block के भीतर fmt: off और fmt: on से कुछ formatting को रोका जा सकता है
  • पूरे Markdown document area को <!-- fmt: off --> और <!-- fmt: on --> HTML comments से बाहर रखा जा सकता है
  • सभी Markdown files को बाहर रखना हो तो extend-exclude में *.md जैसा glob दें
  • विस्तृत व्यवहार Markdown code formatting docs में देखा जा सकता है

नए diagnostic suppression comments

  • v0.15 के ruff: disable·ruff: enable scope suppression के बाद, v0.16 में ruff: ignore और ruff: file-ignore जोड़े गए हैं
  • ruff: ignore noqa की तरह उसी line के diagnostics को दबा सकता है, या standalone comment के रूप में लिखकर अगली पूरी logical line पर लागू किया जा सकता है
    • कई lines में लिखे गए function header में def से colon तक को एक logical line माना जाता है
  • ruff: file-ignore ruff: noqa की तरह पूरी file में निर्दिष्ट diagnostics को दबाता है
  • हर suppression comment में rule code के बाद लागू करने का कारण लिखा जा सकता है
  • --add-ignore CLI option ज़रूरी ruff: ignore comments अपने-आप जोड़ देता है
  • preview mode में F401 जैसे code की जगह unused-import जैसे rule names भी इस्तेमाल किए जा सकते हैं
  • पूरी comment specification Ruff linter docs में दी गई है

fix diff और output formats

  • check और format पहले भी --diff सपोर्ट करते थे, लेकिन वह सामान्य diagnostics से अलग काम करता था, इसलिए fixes की वजह बताने वाले diagnostics के साथ नहीं दिखता था
  • v0.16 का डिफ़ॉल्ट full output जहाँ संभव हो, linter·formatter changes को diagnostic के नीचे diff के रूप में दिखाता है
  • format --check अब linter द्वारा समर्थित सभी output formats का उपयोग कर सकता है
    • machine-readable JSON बनाया जा सकता है
    • ऐसे formats output किए जा सकते हैं जिन्हें GitHub और GitLab CI में comments के रूप में render करते हैं
  • समर्थित formats CLI help और output format docs में देखे जा सकते हैं

compatibility और stabilization

  • v0.16 में breaking changes कम हैं, इसलिए ज़्यादातर मामलों में code या settings को बहुत बदले बिना update किया जा सकता है
  • JSON output में filename, location, end_location, fix.edits[].location, fix.edits[].end_location अब empty string या line 1, column 1 को default मानने के बजाय null हो सकते हैं
    • अभी इससे प्रभावित diagnostics बहुत कम हैं, लेकिन आगे आने वाले rules में यह अधिक आम हो सकता है
  • 12 rules preview से stable state में लाए गए हैं
    • Airflow 3 function signature compatibility AIR303, copyright notice CPY001, float conversion FURB164, sorted min/max FURB192
    • collection literal string concatenation ISC004, exception handler के बाहर exception logging LOG004, गलत bool return type PLE0304
    • excessive positional arguments PLR0917, StopIteration return PLR1708, Union में None की position RUF036
    • class dictionary में annotation access RUF063, __all__ में duplicate items RUF068
  • कुछ मौजूदा rules के stable behavior भी डिफ़ॉल्ट रूप से लागू होते हैं
    • BLE001 अब critical, error, exception के अलावा अन्य logging methods से exception log करने पर भी suppress होता है
    • FA102 अब collections.abc सहित अतिरिक्त PEP 585 compatible APIs की जाँच करता है
    • INT001·INT002·INT003 अब gettext को builtins._ में assign करने जैसे सामान्य usage patterns की भी जाँच करते हैं
    • S310 local string literal bindings को resolve करके false positives कम करता है
    • S508·S509 नवीनतम PySNMP के recommended APIs को सपोर्ट करते हैं
    • UP019 अब सिर्फ typing.Text ही नहीं, typing_extensions.Text को भी पहचानता है
  • पूरे बदलाव GitHub release में देखे जा सकते हैं

1 टिप्पणियां

 
GN⁺ 1 시간 전
Hacker News की राय
  • लगभग 3,000 लाइनों के Python प्रोजेक्ट को v0.15.x से नए version पर अपग्रेड किया; ज़्यादा समय नहीं लगा, और पिछले version से छूट रही कई समस्याएं पकड़ी गईं, जिससे code quality भी बेहतर हुई
    सुझावों के आधार पर manual fixes: https://github.com/nickjj/plutus/commit/9af66d31f98bef841588...
    line length rule फिर से सक्रिय: https://github.com/nickjj/plutus/commit/21789f89bbcee37913c1...
    unused variables पर _ prefix अनिवार्य: https://github.com/nickjj/plutus/commit/a272c77b932e1c78558a...
    Ruff auto-fix: https://github.com/nickjj/plutus/commit/6fe69cf88385ebdf9b8c...

  • Astral के OpenAI द्वारा अधिग्रहण के बाद भी Ruff, ty, uv का सक्रिय रूप से develop होना देखकर अच्छा लगा

    • ty से उम्मीद थी, लेकिन यह basedpyright से काफी पीछे था, इसलिए आखिरकार इस्तेमाल बंद कर दिया। checks की कमी से ज़्यादा false positives घातक थे, और बड़े codebase में बेहद उपयोगी baselining feature भी नहीं था
      uv और Ruff शानदार हैं, और उम्मीद है ty भी कभी उस स्तर तक पहुंचेगा
  • यह देखकर हैरानी होती है कि लोग ऐसे syntax-police tools को लेकर इतने उत्साहित हैं, जो मनमाने rules implement करते हैं और इस बात पर भी सहमत नहीं हो पाते कि अच्छा Python code क्या है
    ये multi-line dictionary को एक line में मिला देते हैं और comments के intent को बिगाड़ देते हैं, फिर दो spaces और double quotes जैसी मामूली formatting ठीक करते हैं। असली समस्या trailing whitespace या import sorting नहीं, बल्कि समझने में मुश्किल 10-line list comprehension है, जिसे ये tools पकड़ नहीं पाते
    workplace में pylint, flake8, black, Ruff इस्तेमाल करते हुए हर बदलाव पर सैकड़ों commits बने, और वह energy कहीं और लगाना बेहतर होता

    • इन tools का उद्देश्य वास्तविक समस्याओं पर ध्यान केंद्रित करवाना है। lint decisions automate करने से PR में formatting पर बहस करते हुए सोचने की क्षमता बर्बाद नहीं करनी पड़ती
      अगर automatic run के results को वैसे ही accept कर लें तो lint discussion से बाहर रह सकते हैं, लेकिन जिन organizations में ऐसे tools नहीं थे, वहां formatting पर सोचने और चर्चा करने में असल समय खर्च करना पड़ा
    • linters समय बर्बाद करते हैं—यह नाराज़गी शायद reasonable स्तर से आगे निकल गई है। field में इसके पर्याप्त प्रमाण हैं कि ये उल्टा समय बचाते हैं, और आखिर में मुद्दा बस इतना है कि linter कभी-कभी ऐसे बदलाव भी करता है जो आपको पसंद नहीं आते
      team development में personal preferences को बहुत ज़ोर से आगे बढ़ाने के बजाय आसपास की राय सुनना और collaboration व craftsmanship की priorities पर फिर से विचार करना ज़रूरी है
    • Ruff line-end comments को पहचानकर हर item को अलग line में रखता है और सिर्फ trailing comma और spaces जोड़ता है। trailing comma हो तो lines को merge भी नहीं करता; दिखाया गया result Black से आया लगता है
      line comment होने पर lines merge करना inappropriate लगता है। double quotes Python में सिर्फ style choice हैं, और अगर single quotes के अंदर double quotes हों तो Ruff भी उन्हें वैसे ही रहने देता है
    • ऐसे tools उल्टा team की energy बचाते हैं। tool न हो तो हर developer के formatting, code quality और readability के standards अलग होते हैं और अंतहीन debate होती रहती है, इसलिए इसे Ruff पर छोड़ना बेहतर है
    • आखिरी item के बाद comma छूट जाने के कारण यह एक line में merge हुआ। कम से कम Black में trailing comma बनाए रखें तो items compress नहीं होते, लेकिन यह intended formatting को अक्सर बिगाड़ता है, इसलिए अब मैं इसे अपने code से connect नहीं करता
  • Go में भी Ruff जैसा tool हो तो अच्छा होगा। कई languages में बढ़िया tools आ रहे हैं, लेकिन Go ecosystem बिखरा हुआ है, और Ruff, Oxc, Biome, Mago जितना polished महसूस होने वाला कोई tool नहीं है

    • Go में बेहतर Go Analysis Framework है: https://pkg.go.dev/golang.org/x/tools/go/analysis
      यह relatively नया है, इसलिए कम जाना जाता है, लेकिन go fix और go vet का आधार है, और लगता है Go team module authors के लिए custom analysis passes define करना आसान बनाने पर काम कर रही है, जो go fix चलाने पर automatically काम करें
      analysis.Analyzer struct से AST, type, SSA information तक access मिलता है और analyzers के बीच information compose की जा सकती है; इसे binary में compile करके go fix को पास करें तो toolchain complex caching तक संभाल लेता है। Go team ने इसे खुद बनाया और toolchain में शामिल किया है, इसलिए golangci-lint जैसे tools भी long term में इस framework में integrate होने की काफी संभावना है
      AI agent से Go Analysis analyzer लिखवाकर go fix से चलाने को कहा जा सकता है, और मैं अपने project में भी vague Markdown instructions के बजाय कई rules को deterministic तरीके से automatically enforce करने के लिए इसका उपयोग कर रहा हूं
    • कुछ समय पहले तक माहौल बिल्कुल उल्टा था: Python community tooling की कमी से जूझ रही थी और सभी Python के लिए gofmt चाहते थे। Ruff formatter नहीं बल्कि linter है, लेकिन हाल में Python ecosystem जिस दिशा में बढ़ रहा है, वह अच्छी लगती है
    • Go ecosystem बिखरा हुआ है—यह बात अच्छी तरह समझ नहीं आती। Go में official formatting और linting tools हैं, और language खुद जानबूझकर सीमित रखी गई है ताकि beginner द्वारा लिखा code भी consistent shape में रहे
      Python या TypeScript के उलट, जहां official tools कोई खास style enforce नहीं करते, Go में Ruff या Biome पहली बार इस्तेमाल करने जैसा dramatic effect मिलना मुश्किल है
    • Go, बड़े IDE के बिना भी इस्तेमाल किए जा सकने वाले सबसे अच्छे language tooling ecosystems में से एक है और golangci-lint भी काफी comprehensive है। Go distribution खुद ही पहले से काफी कुछ solve कर देता है
    • golangci-lint बहुत पहले से मौजूद है और व्यापक रूप से इस्तेमाल होता है
  • डिफ़ॉल्ट रूप से 413 नियम सक्रिय करने से ज़्यादातर projects बिना settings छुए भी उपयोगी lint पा सकेंगे, इसलिए यह अच्छा बदलाव है

    • मौजूदा projects में अचानक 413 संभावित warnings की बौछार होना कितना उपयोगी है, यह सवाल है; यह नए projects के लिए ज़्यादा उपयुक्त लगता है
      आजकल agent को तय मानकों के अनुसार सभी lint warnings ठीक करने के लिए कहकर कुछ घंटे छोड़ दें तो हल निकल सकता है, लेकिन Ruff की दी हुई बारीक diagnostics अपने-आप में स्वागतयोग्य है
  • Ruff में भी लागू होने वाले default values के set को तय करने के लिए Nix के stateVersion जैसी सुविधा चाहिए। कई repositories में Ruff update करने पर जब भी नया default rule जुड़ता है, उसे तुरंत बंद करना या violations ठीक करना पड़ता है, जिससे नतीजे predict करना मुश्किल हो जाता है
    सक्रिय करने वाले सभी rules को allow list में लिखा जा सकता है, लेकिन settings को सरल रखना और जब सभी कुछ घंटे दे सकें तब सिर्फ state version बढ़ाना बेहतर है

    • हर project के pyproject.toml में मनचाहा Ruff version pin करना ज़्यादा उचित तरीका है। हर project तैयार होने पर version बढ़ा सकता है, इसलिए कई projects को एक साथ coordinate करने की ज़रूरत नहीं होती, और एक पीछे रह जाए तो बाकी नहीं रुकते
    • मूल लेख के अनुसार Ruff का default rule set 2 साल से ज़्यादा समय तक नहीं बदला था, और आखिरी बदलाव v0.1.0 में हुआ था
      https://github.com/astral-sh/ruff/releases/tag/v0.1.0
  • agent coding के दौर में मजबूत linting पहले से कहीं ज़्यादा अहम है, और और भाषाओं में forbidigo जैसे tools देखना चाहूँगा

    • projects upgrade कर रहा हूँ, लेकिन मन में मिश्रित भाव हैं। जब मैं खुद code लिखता था, तो intuition के आधार पर तय करता था कि किसी rule को कब skip या ignore करना है, लेकिन जिन projects में ज़्यादातर pylint rules active थे, वहाँ उल्टा pylint को satisfy करने वाली tricks की वजह से code पढ़ना मुश्किल हो गया था
      coding agents भी छोटी-मोटी समस्याएँ ठीक करने में बहुत tokens खर्च करते हैं, या tests fail होने पर उन्हें सीधे disable कर देते हैं। AI outputs की overall accuracy पर भरोसा होने लगा है, लेकिन code quality पर उसकी judgement पर अब भी भरोसा करना मुश्किल है
  • rules 413 तक हैं, फिर भी हर बार किसी नए codebase में जुड़ते ही import sorting को लेकर वही तीन बहसें दोहरानी पड़ती हैं

  • अब लगता है कि zero-config usage recommend किया जा रहा है, यह अच्छी बात है। नए .ruff.toml में सिर्फ line-length = 300 रखना होगा