2 पॉइंट द्वारा GN⁺ 2024-07-26 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • WAT Python runtime में अज्ञात objects की पहचान जल्दी समझने के लिए एक inspector है, जिससे type, value, attributes, methods, parent types, signature, documentation और source code तक एक साथ देखा जा सकता है
  • इसका मूल उपयोग wat / object है, जो wat(object) जैसा ही काम करता है, और wat.short / 'foo', 'foo' | wat.short, wat('foo', short=True) जैसी कई syntaxes को support करता है
  • .short, .dunder, .long, .code, .caller, .public, .all, .ret, .str जैसे modifiers को chain करके output scope, return method, color output और call location display को adjust किया जा सकता है
  • installation pip install wat के बाद import wat से किया जा सकता है, और quick debugging के लिए Insta-Load snippet को Python session में paste करके उसी session में बिना install किए भी इस्तेमाल किया जा सकता है
  • Django User, re.match, pathlib, colorsys.hsv_to_rgb, typing.List[str], str | None जैसे examples दिखाते हैं कि WAT debugging, REPL exploration और Python internals सीखने में उपयोगी हो सकता है

WAT क्या करता है

  • WAT Python objects को runtime पर explore और inspect करने का tool है
  • जब यह समझना मुश्किल हो कि कोई अज्ञात object क्या है, तो Python console में wat inspector से उस object की पहचान की जांच की जा सकती है
  • किसी भी object पर wat / object चलाने से निम्न जानकारी देखी जा सकती है
    • object का type
    • formatted value
    • variables और methods
    • parent types
    • signature
    • documentation
    • source code
  • वही गहन inspection wat(object) syntax से भी इस्तेमाल किया जा सकता है
  • Wat को English what का variation बताया गया है, जो confusion या annoyance व्यक्त करने के लिए इस्तेमाल होने वाला शब्द है

मूल उपयोग और syntax

  • जल्दी input देने के लिए division operator का उपयोग करता है
    • wat / foo, wat(foo) के समान है
  • समान inspection के लिए कई syntaxes इस्तेमाल की जा सकती हैं
    • wat.short / 'foo': quick input के लिए syntax
    • wat.short('foo')
    • wat('foo', short=True): natural Python syntax
    • 'foo' | wat.short: Unix pipe style syntax
  • wat.modifier / foo form से inspection behavior adjust किया जा सकता है
  • modifiers को chain किया जा सकता है; example wat.short.str.gray / 'foo' है
  • Python में objects में सिर्फ data structures ही नहीं, बल्कि functions, classes, modules, built-in types आदि भी शामिल होते हैं, इसलिए wat किसी भी object को explore कर सकता है
  • interpreter में wat type करने पर wat object के बारे में help देखी जा सकती है

Modifiers से inspection scope adjust करना

  • .short या .s object के अंदर variables और methods जैसे attributes छिपाकर केवल value, type, parent types, signature और documentation output करता है
  • .dunder, __ से शुरू होने वाले dunder attributes दिखाता है
  • .long abbreviated न किए गए value और docstring दिखाता है
  • .code functions, methods और classes का source code दिखाता है
  • .nodocs functions और classes की documentation छिपाता है
  • .caller दिखाता है कि inspection कैसे और कहां call हुआ, और यह REPL के बजाय files में काम करता है
  • .public private attributes छिपाकर सिर्फ public attributes दिखाता है
  • .all सभी संभव जानकारी शामिल करता है
  • .ret inspection के बाद object को फिर से return करता है
  • .str output के बजाय result string return करता है
  • .gray console में color output disable करता है
  • .color console में color output force करता है
  • wat.locals local variables inspect करता है, और wat.globals global variables inspect करता है

Installation और Insta-Load

  • pip installation flow इस प्रकार है
    • pip install wat
    • Python में import wat
  • wat package की external dependencies नहीं हैं
  • quick debugging के लिए उसी Python session में बिना install किए इस्तेमाल करने योग्य Insta-Load method देता है
  • Insta-Load में base64, zlib import करने के बाद compressed और encoded code string को restore करके exec(..., globals()) से चलाने वाला Python snippet interpreter में paste किया जाता है
  • Insta-Load snippet चलाने के बाद wat object इस्तेमाल किया जा सकता है
  • snippet चलाने से पहले execute होने वाली चीज़ को verify करने की सिफारिश की जाती है
    • print(zlib.decompress(base64.b64decode(code)).decode()) से extracted code content पहले देखा जा सकता है
    • inspection.py की contents को interpreter में paste करने से भी वही effect मिलता है
    • pip से package install करके code review करने का तरीका भी बताया गया है
  • WAT को single Unicode glyph से load किया जा सकता है
  • Unicode string-based loader लंबी emoji और combining character string को ord(c) & 255 से bytes में बदलकर zlib.decompress(...) के बाद exec(...) से run करने के form में है

Object type और usage समझना

  • Python जैसी dynamically typed language में object type समझना कभी-कभी कठिन हो सकता है, और WAT Inspector type name तथा वह type किस module से आया है, दिखाता है
  • type checking examples value, type और length साथ में दिखाते हैं
    • wat.short / (1,) value (1,), type tuple, length 1 output करता है
    • wat.short / {None} value {None}, type set, length 1 output करता है
  • Django User object example में wat.short / user, str: admin, repr: <User: admin>, type django.contrib.auth.models.User और parent type list output करता है
  • actual type की पुष्टि करने के बाद code में type annotations डालकर आगे की confusion कम की जा सकती है
  • अज्ञात object का usage समझते समय method list, signatures और docstring output किए जा सकते हैं
    • example के रूप में wat / ['foo'] दिया गया है
    • पूरा docstring देखना हो तो wat.long इस्तेमाल करें
  • function usage समझने के लिए function की docstring और signature देखी जा सकती है
    • example के रूप में wat / str.split दिया गया है

Attributes, modules और source code explore करना

  • inspect किए जा रहे object के अंदर देखने के लिए attributes और प्रत्येक attribute का type list किया जा सकता है
    • example के रूप में wat / re.match('(\d)_(.*)', '1_title') दिया गया है
  • modules explore करने के लिए भी इसका उपयोग किया जा सकता है, और चुने गए module के functions, classes और submodules list किए जा सकते हैं
    • import pathlib के बाद wat / pathlib चलाने का example है
    • इसके बाद wat / pathlib.fnmatch की तरह और गहराई में explore किया जा सकता है
  • WAT Inspector default रूप से __ से शुरू होने वाले attributes छिपाता है
    • wat.dunder / {} से dunder attributes देखे जा सकते हैं
  • कोई function असल में कैसे काम करता है, यह देखने के लिए source code देखा जा सकता है
    • import colorsys के बाद wat.code / colorsys.hsv_to_rgb चलाने का example है
  • nested dict और list indentation वाले readable form में format होते हैं

Debugging session और variable inspection

  • Python के breakpoint() से interactive debugger चलाने के बाद, उसी जगह object inspect किया जा सकता है
  • Pdb example में import wat या Insta-Load snippet paste करने के बाद wat / foo से local variable inspect किया जाता है, और c से execution continue होता है
  • local variables और global variables क्रमशः wat.locals, wat.globals से देखे जा सकते हैं
  • wat() को बिना arguments call करने पर caller stack के local variables Local variables title के साथ output होते हैं

Python internals सीखने के examples

  • Python internals को समझने के learning-use examples शामिल हैं
  • reversed([]) == reversed([]) False है, और wat.s / reversed([]) दिखाता है कि value list_reverseiterator object है और type list_reverseiterator है
  • wat / type('ObjectCreator', (), {}) dynamically बनाई गई class की value, type type, signature: class ObjectCreator() दिखाता है
  • wat / type खुद type की value, type type, class type(…) signature, type(object) -> the object's type, type(name, bases, dict, **kwds) -> a new type documentation, public attribute mro आदि दिखाता है
  • wat.s / List[str] value typing.List[str], type typing._GenericAlias, parent types typing._BaseGenericAlias, typing._Final, signature def List(*args, **kwargs) दिखाता है
  • wat(str | None) value str | None, type types.UnionType दिखाता है
  • Python built-in objects explore करने के examples के रूप में wat / __builtins__, wat / ... दिए गए हैं
  • WAT खुद को भी inspect किया जा सकता है
    • example के रूप में wat.dunder / wat, wat.code / wat.__truediv__ दिए गए हैं

Internal behavior summary

  • inspect_format(obj, *, short=False, dunder=False, nodocs=False, long=False, code=False, caller=False, public=False, all=False) object inspection result को string के रूप में बनाता है
    • all=True होने पर dunder, long, code, caller साथ में activate होते हैं
    • public=True होने पर private output deactivate होता है
    • sys.stdout.isatty() true होने पर terminal width ली जाती है और output के ऊपर-नीचे separators जोड़े जाते हैं
  • inspection output object value, string representation, type, parent types, length, signature, documentation, source code, attributes section के क्रम में generate होता है
  • attribute inspection dir(obj) को name order में iterate करता है
    • dunder attributes, dunder setting off होने पर exclude होते हैं
    • _ से शुरू होने वाले private attributes, private setting off होने पर exclude होते हैं
    • getattr(obj, key) में BaseException आने पर exception object को value के रूप में इस्तेमाल किया जाता है
  • callable objects के लिए inspect.signature(obj) के आधार पर signature format होता है
    • failure पर (...) form की fallback signature return करता है
    • classes में class , coroutine function में async def , functions, methods, builtins और __name__ वाले objects में def prefix जोड़ा जाता है
  • code=True और object class या callable होने पर inspect.getsource(obj) से source code output होता है
    • OSError, TypeError, IndentationError होने पर failure message return करता है
  • dict और list formatters indentation depth 30 से अधिक होने पर ERROR: too deeply nested return करते हैं

Color output और theme

  • environment variables से color output control किया जा सकता है
    • WAT_COLOR="false" console का color output disable करता है
    • WAT_COLOR="true" non-tty environment में भी color output force करता है
  • WAT_COLORS environment variable से color theme customize की जा सकती है
  • default theme BAR=0;34,TRAIT=1;34,HEAD=1;37,STR=0;32,NUMBER=0;31,NONE=0;35,TRUE=1;32,FALSE=1;31,DOCS=2;37,KEYWORD=0;34,CALLABLE=1;32,VARIABLE=1;33,CODE=0;33 form की ANSI color code mapping है
  • _strip_color(text) regex से ANSI escape sequence हटाता है

प्रेरणा

  • WAT को Rich Inspect से inspiration मिली है

1 टिप्पणियां

 
GN⁺ 2024-07-26
Hacker News की टिप्पणियां
  • वाह, सच में अच्छा है। पहले इसी तरह के काम के लिए python-ls[0] इस्तेमाल करता था, लेकिन किसी याद न रहने वाली वजह से कुछ टूट गया और अब वह maintain भी नहीं होता
    इसे अपने debugging टूलबॉक्स में जोड़ने वाला हूं, जो मुख्य तौर पर snoop[1] और pdbpp से बना है। wat से मेरी इच्छा बस इतनी है कि Jupyter में object exploration आसान करने वाला कोई ipy widget हो
    base64 exec hack भी पसंद आया। Python लंबे समय से इस्तेमाल कर रहा हूं, फिर भी अब तक इसके बारे में न सोचा था न देखा था, इसलिए आगे कुछ उपयोगों में इसे जरूर आजमाऊंगा
    [0] https://github.com/gabrielcnr/python-ls
    [1] https://pypi.org/project/snoop/

    • Jupyter में objects देखने के लिए, अगर NumPy-टाइप काम ज्यादा है तो penzai भी देखने लायक है: https://github.com/google-deepmind/penzai
  • दिलचस्प लग रहा है। Python में dir हमेशा इस्तेमाल करता हूं, और जब docs खास अच्छी नहीं होतीं तो कभी-कभी official docs से भी ज्यादा उपयोगी होता है
    interactive shell Python की असली ताकतों में से एक है, इसलिए हैरानी होती है कि उसके आसपास ऐसे नए tools या innovations ज्यादा नहीं हैं

    • help() function भी है। वाकई उपयोगी है
  • पुराने icecream का ज्यादा चमकदार version लगता है
    https://github.com/gruns/icecream
    अगर नहीं जानते, तो नीचे दूसरे languages के implementations की list भी देख सकते हैं
    https://github.com/gruns/icecream#icecream-in-other-language...

  • इस तरह के tools उपयोगी होते हैं
    20 साल पहले मैंने Zope के लिए object introspector बनाया था
    आजकल devtools रोज इस्तेमाल करता हूं, और icecream व q कभी-कभी। wat भी एक बार आजमाऊंगा

  • from wat import wat
    project का स्वभाव इतना मजेदार है, फिर भी हैरानी है कि उसी usage syntax के साथ सिर्फ import wat क्यों नहीं दिया। तब जिज्ञासु users wat/wat करके trick खोज सकते थे

    • import wat अच्छा होता, लेकिन Python में module को callable बनाने की सीमा है। इसलिए लंबे from wat import wat पर जाना पड़ा
      पक्का नहीं, लेकिन import wat; wat.wat / object शायद ज्यादा सुविधाजनक हो सकता है
  • बहुत उपयोगी दिखता है, लेकिन क्या सिर्फ मुझे ही readability के नाम पर बिल्कुल असंबंधित operators—यहां / operator—को overload करने का हालिया चलन खटकता है?

    • सहमत हूं कि इस मामले में / overload करना अजीब choice है। फिर भी अफसोस है कि is को overload नहीं किया जा सकता। असल में wat(foo) ही काफी होता
  • झंझट वाले import से बचने के लिए $PYTHONSTARTUP file में यह भी जोड़ सकते हैं
    try:
    from wat import wat
    except ImportError:
    pass

    • बल्कि आप काफी शानदार base64 inline importer भी जोड़ सकते हैं
      आखिर में मैंने उसका output print करके उसे उस directory में रख दिया, जिसकी ओर PYTHONPATH point करता है, ताकि हमेशा इस्तेमाल कर सकूं
      देखना होगा कि लगातार इस्तेमाल करूंगा या नहीं
  • वाह, Python सीखते समय ऐसा tool होता तो शायद game changer होता। भाषा सीखते समय अंदर क्या हो रहा है यह देखना critical path है, और Python की default debugging, अच्छी से अच्छी हालत में भी, निराशाजनक है
    इसके बजाय मैंने pry install किया और Ruby का उत्साही fan बन गया, लेकिन यह tool मुझे Python को फिर से try करने पर मजबूर कर सकता है

  • लेखक functionality देने के लिए अंदर से standard library का Python inspect module इस्तेमाल कर रहे हैं। बेशक उसके ऊपर काफी added value भी दी है
    wat module की inspection.py देखें
    दूसरी line में यह है:
    import inspect as std_inspect

  • “अगर आप जल्दी से कुछ debug करना चाहते हैं, तो उसी session में कुछ भी install किए बिना इस inspector का इस्तेमाल कर सकते हैं”
    “इस snippet को Python interpreter में paste करके तुरंत load करें”
    project README में पूरे project की copy को base64-encoded compressed data के रूप में डालने का idea काफी चतुर है
    खासकर ऐसे project के लिए यह ठीक बैठता है, जिसे शायद आप पहले से उन environments में डालने के बारे में न सोचें जहां इसकी जरूरत पड़ेगी