एक .py फ़ाइल को पार्स करें, एएसटी पढ़ें, इसे संशोधित करें, फिर संशोधित स्रोत कोड वापस लिखें


168

मैं प्रोग्रामर सोर्स कोड को प्रोग्रामेटिक रूप से एडिट करना चाहता हूं। मूल रूप से मैं एक .pyफ़ाइल पढ़ना चाहता हूं , एएसटी उत्पन्न करता हूं , और फिर संशोधित अजगर स्रोत कोड (यानी दूसरी .pyफ़ाइल) वापस लिखता हूं ।

पायथॉन स्रोत कोड को पार्स / संकलित करने के तरीके हैं, जैसे मानक पायथन मॉड्यूल का उपयोग कर astया compiler। हालाँकि, मुझे नहीं लगता कि उनमें से कोई भी स्रोत कोड को संशोधित करने के तरीकों का समर्थन करता है (उदाहरण के लिए इस फ़ंक्शन को हटाएं) और फिर संशोधित करने वाले अजगर स्रोत कोड को वापस लिखें।

अद्यतन: इसका कारण यह है कि मैं यह करना चाहता हूं कि मैं अजगर के लिए एक म्यूटेशन टेस्टिंग लाइब्रेरी लिखना चाहता हूं , ज्यादातर बयानों / अभिव्यक्तियों, पुनरावर्ती परीक्षणों को हटाकर और क्या टूटता है।


4
संस्करण 2.6 के बाद से पदावनत: पायथन 3.0 में कंपाइलर पैकेज को हटा दिया गया है।
डेफा

1
क्या आप स्रोत को संपादित नहीं कर सकते? आप डेकोरेटर क्यों नहीं लिख सकते?
एस.लॉट।

3
पवित्र गाय! मैं एक ही तकनीक (विशेष रूप से एक नाक प्लगइन बनाने) का उपयोग करके अजगर के लिए एक उत्परिवर्तन परीक्षक बनाना चाहता था, क्या आप इसे सोर्सिंग योजना बना रहे हैं?
रयान

2
@ रयान हाँ, मैं जो भी स्रोत बनाऊँगा उसे खोलूँगा। हमें इस पर संपर्क रखना चाहिए
रोरी

1
निश्चित रूप से, मैंने आपको लॉन्चपैड के माध्यम से एक ईमेल भेजा।
रयान

जवाबों:


73

पाइथोस्कोप परीक्षण के मामलों में ऐसा करता है जो स्वचालित रूप से 2to3 करता है अजगर 2.6 के लिए टूल (यह अजगर 2.x स्रोत को अजगर 3.x स्रोत में परिवर्तित करता है)।

ये दोनों उपकरण lib2to3 लाइब्रेरी का उपयोग करते हैं जो कि अजगर पार्सर / कंपाइलर मशीनरी का एक कार्यान्वयन है जो स्रोत में टिप्पणियों को संरक्षित कर सकता है जब यह स्रोत से राउंड ट्रिप किया गया है -> एएसटी -> स्रोत।

रस्सी परियोजना यदि आप रूपांतरण की तरह अधिक पुनर्रचना करना चाहते हैं अपनी जरूरतों को पूरा कर सकते हैं।

Ast मॉड्यूल अपने अन्य विकल्प है, और वहाँ कैसे "unparse" वाक्य रचना के पेड़ के लिए कोड में वापस के एक पुराने उदाहरण है (पार्सर मॉड्यूल का उपयोग)। लेकिन astमॉड्यूल तब अधिक उपयोगी होता है जब एएसटी कोड पर परिवर्तित होता है जो तब कोड ऑब्जेक्ट में बदल जाता है।

Redbaron परियोजना भी एक अच्छा फिट हो सकता है (एचटी जेवियर Combelle)


5
unparse उदाहरण अभी भी बनाए रखा है, यहाँ अद्यतन py3k संस्करण है: hg.python.org/cpython/log/tip/Tools/parser/unparse.py
जानूस Troelsen

2
unparse.pyस्क्रिप्ट के संबंध में - किसी अन्य स्क्रिप्ट से इसका उपयोग करना वास्तव में बोझिल हो सकता है। लेकिन, एक पैकेज है जिसे अस्टुनपर्से (जीथब पर , पिपी पर ) कहा जाता है , जो मूल रूप से एक ठीक से पैक किया गया संस्करण है unparse.py
mbdevpl

क्या आप शायद पसंदीदा विकल्प के रूप में पार्सो जोड़कर अपने जवाब को अपडेट कर सकते हैं? यह बहुत अच्छा और अपडेटेड है।
बॉक्सिंग

59

बिल्ट एस्ट्रो मॉड्यूल को वापस स्रोत में बदलने की विधि नहीं है। हालाँकि, कोडन मॉड्यूल यहाँ पर बहुत अच्छा प्रिंटर प्रदान करता है जो आपको ऐसा करने में सक्षम करेगा। जैसे।

import ast
import codegen

expr="""
def foo():
   print("hello world")
"""
p=ast.parse(expr)

p.body[0].body = [ ast.parse("return 42").body[0] ] # Replace function body with "return 42"

print(codegen.to_source(p))

यह प्रिंट करेगा:

def foo():
    return 42

ध्यान दें कि आप सटीक स्वरूपण और टिप्पणियां खो सकते हैं, क्योंकि ये संरक्षित नहीं हैं।

हालाँकि, आपको इसकी आवश्यकता नहीं हो सकती है। यदि आप सभी की आवश्यकता प्रतिस्थापित एएसटी को निष्पादित करने के लिए है, तो आप बस इसे आश्चर्यजनक पर संकलन () कॉल करके कर सकते हैं, और परिणामस्वरूप कोड ऑब्जेक्ट को निष्पादित कर सकते हैं।


20
भविष्य में इसका उपयोग करने वाले किसी के लिए, कोडेन काफी हद तक पुराना है और इसमें कुछ कीड़े हैं। मैंने उनमें से कुछ तय किया है; मैं इसे गीथुब
मैटबस्टा

ध्यान दें कि नवीनतम कोडजेन 2012 में अपडेट किया गया है जो उपरोक्त टिप्पणी के बाद है, इसलिए मुझे लगता है कि कोडगेन अपडेट किया गया है। @mattbasta
zjffdu

4
एस्टर को codegen एक बनाए रखा उत्तराधिकारी हो गया लगता है
medmunds

20

एक अलग उत्तर में मैंने astorपैकेज का उपयोग करने का सुझाव दिया , लेकिन मैंने तब से एक अधिक अप-टू-डेट एएसटी अन-पार्सिंग पैकेज पाया है astunparse:

>>> import ast
>>> import astunparse
>>> print(astunparse.unparse(ast.parse('def foo(x): return 2 * x')))


def foo(x):
    return (2 * x)

मैंने इसका परीक्षण पायथन 3.5 पर किया है।


19

आपको स्रोत कोड को फिर से बनाने की आवश्यकता नहीं हो सकती है। यह कहना मेरे लिए थोड़ा खतरनाक है, ज़ाहिर है, क्योंकि आपने वास्तव में यह नहीं बताया है कि आपको क्यों लगता है कि आपको कोड से भरी एक .py फ़ाइल तैयार करनी होगी; परंतु:

  • यदि आप एक .py फ़ाइल जनरेट करना चाहते हैं, जिसका लोग वास्तव में उपयोग करेंगे, तो शायद वे एक फ़ॉर्म भर सकें और एक उपयोगी .py फ़ाइल अपने प्रोजेक्ट में सम्मिलित कर सकें, तो आप इसे एएसटी में बदलना नहीं चाहते हैं। वापस क्योंकि आप सभी स्वरूपण खो देंगे (उन खाली लाइनों के बारे में सोचें जो पायथन को एक साथ संबंधित लाइनों के समूह के समूह द्वारा पढ़ने योग्य बनाती हैं) ( आश्चर्यजनक नोड्स linenoऔर col_offsetविशेषताएँ ) टिप्पणियां हैं। इसके बजाय, आप संभवत: .py फ़ाइल को अनुकूलित करने के लिए एक टेम्प्लेटिंग इंजन ( Django टेम्पलेट भाषा , उदाहरण के लिए, टेम्प्लेटिंग को भी आसान बनाने के लिए डिज़ाइन किया गया है) का उपयोग करना चाहते हैं, या फिर रिक कोपलैंड के MetaPython एक्सटेंशन का उपयोग करें।

  • यदि आप किसी मॉड्यूल के संकलन के दौरान बदलाव करने की कोशिश कर रहे हैं, तो ध्यान दें कि आपको पाठ पर वापस जाने की ज़रूरत नहीं है; आप सीधे एएसपी को सीधे एक .py फ़ाइल में बदलने के बजाय संकलित कर सकते हैं।

  • लेकिन लगभग किसी भी और हर मामले में, आप शायद कुछ गतिशील करने की कोशिश कर रहे हैं कि पायथन जैसी भाषा वास्तव में बहुत आसान है, बिना नई .py फाइलें लिखे! यदि आप अपने प्रश्न का विस्तार करते हैं, तो हमें बताएं कि आप वास्तव में क्या हासिल करना चाहते हैं, नई .py फाइलें संभवत: उत्तर में शामिल नहीं होंगी; मैंने पायथन प्रोजेक्ट्स को सैकड़ों वास्तविक दुनिया की चीजों को करते देखा है, और उनमें से एक भी नहीं है जो कभी भी एक थकाऊ फ़ाइल के लिए आवश्यक हो। इसलिए, मुझे स्वीकार करना चाहिए, मुझे थोड़ा संदेह है कि आपने पहला अच्छा उपयोग-मामला पाया है। :-)

अपडेट: अब जब आपने समझाया कि आप क्या करने की कोशिश कर रहे हैं, तो मुझे वैसे भी एएसटी पर काम करने के लिए लुभाया जाएगा। आप किसी फ़ाइल की पंक्तियों को हटाकर, (जो आधे-अधूरे बयानों के साथ मर सकते हैं, केवल एक सिंटेक्सऑयर के साथ मर सकते हैं) को म्यूट करना चाहेंगे, लेकिन पूरे बयान - और एएसटी की तुलना में इसे करने के लिए बेहतर जगह क्या है?


संभावित समाधान और संभावित विकल्पों का अच्छा अवलोकन।
रयान

1
कोड जनरेशन के लिए वास्तविक दुनिया का उपयोग मामला: किड और गेन्शी (मेरा मानना ​​है) डायनामिक पेजों के तेजी से प्रतिपादन के लिए XML टेम्प्लेट से पायथन उत्पन्न करते हैं।
रिक कोपलैंड

10

कोड संरचना को पार्स करना और संशोधित करना निश्चित रूप से astमॉड्यूल की मदद से संभव है और मैं इसे एक क्षण में एक उदाहरण में दिखाऊंगा। हालांकि, संशोधित स्रोत कोड को वापस लिखना astअकेले मॉड्यूल के साथ संभव नहीं है । इस काम के लिए अन्य मॉड्यूल उपलब्ध हैं जैसे कि यहां एक ।

नोट: नीचे दिए गए उदाहरण को astमॉड्यूल के उपयोग पर एक परिचयात्मक ट्यूटोरियल के रूप में माना जा सकता है, लेकिन astमॉड्यूल का उपयोग करने पर अधिक व्यापक मार्गदर्शिका यहां ग्रीन ट्री सांप ट्यूटोरियल और मॉड्यूल पर आधिकारिक प्रलेखन में उपलब्ध astहै

का परिचय ast:

>>> import ast
>>> tree = ast.parse("print 'Hello Python!!'")
>>> exec(compile(tree, filename="<ast>", mode="exec"))
Hello Python!!

आप केवल एपीआई को कॉल करके अजगर कोड (स्ट्रिंग में दर्शाए गए) को पार्स कर सकते हैं ast.parse()। यह सार सिंटैक्स ट्री (एएसटी) संरचना को संभालता है। दिलचस्प है कि आप इस संरचना को वापस संकलित कर सकते हैं और इसे ऊपर बताए अनुसार निष्पादित कर सकते हैं।

एक और बहुत उपयोगी एपीआई है ast.dump()जो पूरे एएसटी को एक स्ट्रिंग रूप में डंप करता है। इसका उपयोग पेड़ की संरचना का निरीक्षण करने के लिए किया जा सकता है और यह डिबगिंग में बहुत सहायक है। उदाहरण के लिए,

पायथन 2.7 पर:

>>> import ast
>>> tree = ast.parse("print 'Hello Python!!'")
>>> ast.dump(tree)
"Module(body=[Print(dest=None, values=[Str(s='Hello Python!!')], nl=True)])"

पायथन 3.5 पर:

>>> import ast
>>> tree = ast.parse("print ('Hello Python!!')")
>>> ast.dump(tree)
"Module(body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Str(s='Hello Python!!')], keywords=[]))])"

पायथन 2.7 बनाम पायथन 3.5 में प्रिंट स्टेटमेंट के लिए वाक्यविन्यास में अंतर और संबंधित पेड़ों में एएसटी नोड के प्रकार में अंतर को नोटिस करें।


कोड का उपयोग करके संशोधन कैसे करें ast:

अब, आइए astमॉड्यूल द्वारा अजगर कोड के संशोधन के उदाहरण पर एक नज़र डालते हैं । एएसटी संरचना को संशोधित करने का मुख्य उपकरण ast.NodeTransformerवर्ग है। जब भी किसी को एएसटी को संशोधित करने की आवश्यकता होती है, तो उसे इससे उप-विभाजन करने की आवश्यकता होती है और तदनुसार नोड ट्रांसफॉर्मेशन लिखना होता है।

हमारे उदाहरण के लिए, आइए एक साधारण उपयोगिता लिखने का प्रयास करें जो पायथन 2 को रूपांतरित करता है, पायथन 3 फ़ंक्शन कॉल को स्टेटमेंट प्रिंट करता है।

फ़न कॉल कनवर्टर उपयोगिता के लिए प्रिंट स्टेटमेंट: Print2to3.py:

#!/usr/bin/env python
'''
This utility converts the python (2.7) statements to Python 3 alike function calls before running the code.

USAGE:
     python print2to3.py <filename>
'''
import ast
import sys

class P2to3(ast.NodeTransformer):
    def visit_Print(self, node):
        new_node = ast.Expr(value=ast.Call(func=ast.Name(id='print', ctx=ast.Load()),
            args=node.values,
            keywords=[], starargs=None, kwargs=None))
        ast.copy_location(new_node, node)
        return new_node

def main(filename=None):
    if not filename:
        return

    with open(filename, 'r') as fp:
        data = fp.readlines()
    data = ''.join(data)
    tree = ast.parse(data)

    print "Converting python 2 print statements to Python 3 function calls"
    print "-" * 35
    P2to3().visit(tree)
    ast.fix_missing_locations(tree)
    # print ast.dump(tree)

    exec(compile(tree, filename="p23", mode="exec"))

if __name__ == '__main__':
    if len(sys.argv) <=1:
        print ("\nUSAGE:\n\t print2to3.py <filename>")
        sys.exit(1)
    else:
        main(sys.argv[1])

इस उपयोगिता को छोटे उदाहरण फ़ाइल पर आज़माया जा सकता है, जैसे नीचे एक, और इसे ठीक काम करना चाहिए।

इनपुट फ़ाइल का परीक्षण करें: py2.py

class A(object):
    def __init__(self):
        pass

def good():
    print "I am good"

main = good

if __name__ == '__main__':
    print "I am in main"
    main()

कृपया ध्यान दें कि उपरोक्त परिवर्तन केवल astट्यूटोरियल उद्देश्य के लिए है और वास्तविक स्थिति में सभी को अलग-अलग परिदृश्यों जैसे कि देखना होगा print " x is %s" % ("Hello Python")


6

मैंने हाल ही में काफी स्थिर बनाया है (कोर वास्तव में अच्छी तरह से परीक्षण किया गया है) और कोड का एक्स्टेंसिबल टुकड़ा है जो astपेड़ से कोड उत्पन्न करता है : https://github.com/paluh/code-formatter

मैं अपनी परियोजना को एक छोटे विम प्लगइन के लिए एक आधार के रूप में उपयोग कर रहा हूं (जो मैं हर दिन उपयोग कर रहा हूं), इसलिए मेरा लक्ष्य वास्तव में अच्छा और पठनीय अजगर कोड उत्पन्न करना है।

पुनश्च मैंने विस्तार करने की कोशिश की है, codegenलेकिन यह आर्किटेक्चर ast.NodeVisitorइंटरफेस पर आधारित है, इसलिए फॉर्मेटर्स (visitor_ विधियां) केवल कार्य हैं। मैंने इस संरचना को काफी सीमित और कठिन पाया है (लंबे और नेस्टेड अभिव्यक्तियों के मामले में वस्तुओं के पेड़ को रखना आसान है और कुछ आंशिक परिणामों को कैश करना - दूसरे तरीके से आप घातीय जटिलता को हिट कर सकते हैं यदि आप सर्वश्रेष्ठ लेआउट की खोज करना चाहते हैं)। लेकिन codegen मित्सुहिको के काम के हर टुकड़े के रूप में (जो मैंने पढ़ा है) बहुत अच्छी तरह से लिखा और संक्षिप्त है।


4

अन्य जवाबों में से एक की सिफारिश की गई है codegen, जो लगता है कि द्वारा सुपररेटेड किया गया है astor। के संस्करण astorPyPI पर (इस लेखन के रूप में संस्करण 0.5) एक छोटे से रूप में अच्छी तरह पुराना हो करने के लिए, आप के विकास के संस्करण को स्थापित कर सकते हैं ताकि लगता है astorइस प्रकार है।

pip install git+https://github.com/berkerpeksag/astor.git#egg=astor

तब आप astor.to_sourceपायथन एएसटी को मानव-पठनीय पायथन स्रोत कोड में परिवर्तित करने के लिए उपयोग कर सकते हैं :

>>> import ast
>>> import astor
>>> print(astor.to_source(ast.parse('def foo(x): return 2 * x')))
def foo(x):
    return 2 * x

मैंने इसका परीक्षण पायथन 3.5 पर किया है।


4

यदि आप इसे 2019 में देख रहे हैं, तो आप इस libcst पैकेज का उपयोग कर सकते हैं । इसमें ast के समान वाक्य रचना है। यह एक आकर्षण की तरह काम करता है, और कोड संरचना को संरक्षित करता है। यह मूल रूप से उस परियोजना के लिए सहायक है जहां आपको टिप्पणियों, व्हाट्सएप, न्यूलाइन आदि को संरक्षित करना है।

यदि आपको संरक्षित टिप्पणियों, व्हाट्सएप और अन्य के बारे में परवाह करने की आवश्यकता नहीं है, तो खगोल और एस्टोर का संयोजन अच्छी तरह से काम करता है।


2

हमें इसी तरह की आवश्यकता थी, जो यहां अन्य उत्तरों से हल नहीं हुई। इसलिए हम इस, के लिए एक पुस्तकालय बनाया ASTTokens है, जो एक एएसटी पेड़ के साथ उत्पादन लेता ast या astroid मॉड्यूल, और मूल स्रोत कोड में पाठ की सीमाओं के साथ यह निशान।

यह सीधे कोड में संशोधन नहीं करता है, लेकिन यह शीर्ष पर जोड़ना मुश्किल नहीं है, क्योंकि यह आपको पाठ की सीमा बताता है जिसे आपको संशोधित करने की आवश्यकता है।

उदाहरण के लिए, यह एक फ़ंक्शन कॉल को कवर करता है WRAP(...), टिप्पणियों और अन्य चीजों को संरक्षित करता है:

example = """
def foo(): # Test
  '''My func'''
  log("hello world")  # Print
"""

import ast, asttokens
atok = asttokens.ASTTokens(example, parse=True)

call = next(n for n in ast.walk(atok.tree) if isinstance(n, ast.Call))
start, end = atok.get_text_range(call)
print(atok.text[:start] + ('WRAP(%s)' % atok.text[start:end])  + atok.text[end:])

पैदा करता है:

def foo(): # Test
  '''My func'''
  WRAP(log("hello world"))  # Print

उम्मीद है की यह मदद करेगा!


1

एक प्रोग्राम ट्रांसफ़ॉर्मेशन सिस्टम एक उपकरण है जो स्रोत पाठ को पार्स करता है, एएसटीएस बनाता है, आपको स्रोत-से-स्रोत परिवर्तनों का उपयोग करके उन्हें संशोधित करने की अनुमति देता है ("यदि आप इस पैटर्न को देखते हैं, तो इसे उस पैटर्न द्वारा प्रतिस्थापित करें")। इस तरह के उपकरण मौजूदा स्रोत कोड के म्यूटेशन करने के लिए आदर्श हैं, जो सिर्फ "यदि आप इस पैटर्न को देखते हैं, तो पैटर्न संस्करण द्वारा प्रतिस्थापित करें"।

बेशक, आपको एक प्रोग्राम ट्रांसफ़ॉर्मेशन इंजन की ज़रूरत है जो आपकी रुचि की भाषा को पार्स कर सके, और फिर भी पैटर्न-निर्देशित ट्रांसफ़ॉर्मेशन कर सके। हमारा डीएमएस सॉफ्टवेयर रेन्गिनियरिंग टूलकिट एक ऐसी प्रणाली है जो ऐसा कर सकती है, और पायथन, और कई अन्य भाषाओं को संभालती है।

पायथन कैप्चरिंग टिप्पणियों के लिए सटीक रूप से डीएमएस-पार्स एएसटी के उदाहरण के लिए इस एसओ उत्तर को देखें । डीएमएस एएसटी में बदलाव कर सकता है और टिप्पणियों सहित मान्य पाठ को पुन: उत्पन्न कर सकता है। आप इसे एएसटी को पूर्व-निर्धारित करने के लिए कह सकते हैं, अपने स्वयं के प्रारूपण सम्मेलनों (आप इन्हें बदल सकते हैं) का उपयोग कर सकते हैं, या "फ़िडेलिटी प्रिंटिंग" कर सकते हैं, जो मूल लेआउट को अधिकतम करने के लिए मूल रेखा और स्तंभ जानकारी का उपयोग करता है (लेआउट में कुछ बदलाव जहां नया कोड डाला जाता है) अपरिहार्य है।

डीएमएस के साथ पायथन के लिए "म्यूटेशन" नियम को लागू करने के लिए, आप निम्नलिखित लिख सकते हैं:

rule mutate_addition(s:sum, p:product):sum->sum =
  " \s + \p " -> " \s - \p"
 if mutate_this_place(s);

यह नियम "+" को "-" के साथ एक सिंटैक्टिक रूप से सही तरीके से प्रतिस्थापित करता है; यह एएसटी पर काम करता है और इस प्रकार तार या टिप्पणियों को स्पर्श नहीं करेगा जो सही दिखने के लिए होती हैं। "Mutate_this_place" पर अतिरिक्त स्थिति आपको यह नियंत्रित करने देती है कि ऐसा कितनी बार होता है; आप कार्यक्रम में हर जगह को बदलना नहीं चाहते हैं ।

आप स्पष्ट रूप से इस तरह के एक और नियम चाहते हैं जो विभिन्न कोड संरचनाओं का पता लगाते हैं, और उन्हें उत्परिवर्तित संस्करणों द्वारा प्रतिस्थापित करते हैं। डीएमएस नियमों का एक सेट लागू करने के लिए खुश है। उत्परिवर्तित एएसटी तब पूर्व-निर्धारित है।


मैंने 4 साल में इस जवाब को नहीं देखा है। वाह, इसे कई बार डाउनवोट किया गया है। यह वास्तव में आश्चर्यजनक है, क्योंकि यह ओपी के सवाल का सीधे जवाब देता है, और यहां तक ​​कि दिखाता है कि वह उन उत्परिवर्तन को कैसे करना चाहता है जो वह करना चाहता है। मुझे नहीं लगता कि डाउनवोटर्स में से कोई भी यह बताने के लिए परवाह करेगा कि उन्होंने क्यों डाउनवोट किया।
इरा बैक्सटर

4
क्योंकि यह बहुत महंगा, क्लोज्ड सोर्स टूल को बढ़ावा देता है।
ज़ोरान पावलोविच

@ZoranPavlovic: तो आप इसकी किसी भी तकनीकी सटीकता या उपयोगिता पर आपत्ति नहीं कर रहे हैं?
इरा बैक्सटर

2
@Zoran: उन्होंने यह नहीं कहा कि उनके पास एक ओपन सोर्स लाइब्रेरी है। उन्होंने कहा कि वह पायथन सोर्स कोड (एएसटी का उपयोग करके) को संशोधित करना चाहते थे, और जो समाधान उन्हें मिल सकता था, उन्होंने ऐसा नहीं किया। यह एक ऐसा उपाय है। आपको नहीं लगता कि जावा पर पायथन जैसी भाषाओं में लिखे गए कार्यक्रमों पर लोग व्यावसायिक उपकरणों का उपयोग करते हैं?
इरा बैक्सटर

1
मैं कोई मतदाता नहीं हूं, लेकिन पोस्ट एक विज्ञापन की तरह है। उत्तर को बेहतर बनाने के लिए, आप खुलासा कर सकते हैं कि आप उत्पाद से जुड़े हैं
wm

0

मैं इसके लिए बैरन का उपयोग करता था, लेकिन अब पार्सो में बदल गया हूं क्योंकि यह आधुनिक अजगर के साथ अद्यतित है। यह बहुत अच्छा काम करता है।

म्यूटेशन टेस्टर के लिए भी मुझे इसकी आवश्यकता थी। यह वास्तव में काफी सरल है कि आप इसे पारस के साथ बना सकते हैं, https://github.com/boxed/mutmut पर मेरा कोड देखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.