Neat way to port nonpolyglot code from Py2 to Py3

前端 未结 3 2056
抹茶落季
抹茶落季 2021-01-22 10:28

In many of my python modules, I am using

from itertools import izip_longest

But now I am moving my codebase to Py3 (compatible with Py2 at the sa

3条回答
  •  失恋的感觉
    2021-01-22 10:36

    I see your other question got closed so I'll post here. So, there's a couple files, and naming is important!

    fixer.py

    #!/usr/bin/env python3
    # you'll need 2to3 and python-modernize installed
    from __future__ import absolute_import
    import sys
    from lib2to3.main import main
    import libmodernize
    
    sys.path.append(".")
    sys.exit(main('fixers'))
    

    fixers/fix_iziplongest.py

    from lib2to3 import fixer_base
    import libmodernize
    
    class FixIziplongest(fixer_base.BaseFix):
        PATTERN = """
        power< 'izip_longest' trailer< '(' any* ')' > >
        | import_from< 'from' 'itertools' 'import' 'izip_longest' >
        """
    
        # This function is only called on matches to our pattern, which should
        # be usage of izip_longest, and the itertools import
        def transform(self, node, results):
            # add the new import (doesn't matter if we do this multiple times
            libmodernize.touch_import('itertools_compat', 'zip_longest', node)
            # remove the old import
            if node.type == syms.import_from:
                node.parent.remove()
                return node
            
            # rename to izip_longest
            node.children[0].value = 'zip_longest'
            return node
    

    Usage is the same as 2to3 - python ./fixer.py -f iziplongest file_to_fix.py (more flags if you want it to apply changes, that'll just show the diff) So, what this does is it would covert this:

    from itertools import izip_longest
    for x in izip_longest(a, b):
         print(x)
    

    To this:

    from itertools_compat import zip_longest
    for x in zip_longest(a, b):
         print(x)
    

提交回复
热议问题