Skip to content

Instantly share code, notes, and snippets.

@andreberg
Last active February 24, 2020 18:05
Show Gist options
  • Save andreberg/5637758 to your computer and use it in GitHub Desktop.
Save andreberg/5637758 to your computer and use it in GitHub Desktop.
[RegEx: Convert print to print()] Functions to convert between Python 2 and Py3k print statements.Supports string interpolation and multiline strings. Does *NOT* cover Python 2 backslash line continuations completely (yet). I originally wrote it for use in a ruble command in Eclipse Aptana Studio 3. #regex #conversion #python #python3 #ruby #rub…
# -*- coding: utf-8 -*-
#
# == Aptana Ruble Commands
# Convert Between Python 2 and Py3k Print Statements
#
# Created by André Berg on 2013-05-23.
# Copyright 2013 Berg Media. All rights reserved.
#
# Used from a Python.ruble command in Eclipse
# Aptana Studio 3:
#
# command t(:convert_to_py3k_print) do |cmd|
# cmd.output = :replace_selection
# cmd.input = :selection
# cmd.invoke do |context|
# text = "#{STDIN.read}"
# convert_to_py3k_print(text)
# end
# end
=begin rdoc
Convert Python 2 <tt>print ...</tt> statements in +text+ to Python 3 <tt>print(...)</tt> format.
Supports string interpolation and multiline strings.
=end
def convert_to_py3k_print(text)
regex_print_descriptor = /print(\s*)>>(\s*)(.+),\s*(.+)/
regex_print_simple = /print\s+(?![\'\"])([^#\n\r]+(?<! ))?/
regex_print_multiline = /print\s+(ur|ru)?(['"]{1,3})([\w\W]+?)(\2)([^#\n\r]+(?<! ))?/m
regex_print = /print\s+(ur|ru)?(['"])(?!\2)([^\r\n]+)(\2)([^#\n\r]+(?<! ))?/
result = text.gsub(regex_print_descriptor, "print(\\4, file=\\3)")
result.gsub!(regex_print, "print(\\1\\2\\3\\4\\5)")
result.gsub!(regex_print_simple, "print(\\1)")
result.gsub!(regex_print_multiline, "print(\\1\\2\\3\\4\\5)")
result
end
=begin rdoc
Convert Python 3 <tt>print(...)</tt> statements in +text+ to Python 2 <tt>print ... </tt> format.
Supports string interpolation and multiline strings.
=end
def convert_from_py3k_print(text)
regex_print_descriptor = /print\((.+),(\s*)file=(.+)([^#\n\r]+(?<! ))?\)/
regex_print = /print\(([\w\W]+?)\)(%\s*#.*[\r\n])?([^#\n\r]+(?<! ))?/m
regex_line_continuation_fix = /(print\s+.+)%(\s*)(\s*#.*)?([\n\r])(.+)/m
result = text.gsub(regex_print_descriptor, "print >> \\3,\\2\\1")
result.gsub!(regex_print, "print \\1\\2\\3")
result.gsub!(regex_line_continuation_fix, "\\1%\\2\\\\\\4\\5 \\3")
result.rstrip
end
if __FILE__ == $0
require "test/unit"
class TestConvertPythonPrint < Test::Unit::TestCase
def test_convert_to_py3k_print
pairs = [
{:python3 => 'print("bla bla", file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla bla"'},
{:python3 => 'print("bla bla".upper(), file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla bla".upper()'},
{:python3 => 'print("bla %s" % ("bla"), file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla %s" % ("bla")'},
{:python3 => 'print("bla bla".upper(), file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla bla".upper()'},
{:python3 => 'print("bla %s" % ("bla"), file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla %s" % ("bla")'},
{:python3 => 'print("bla %s" % "bla", file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla %s" % "bla"'},
{:python3 => 'print("%r" % adapter)',
:python2 => 'print "%r" % adapter'},
{:python3 => 'print("{0!r}".format("bla"))',
:python2 => 'print "{0!r}".format("bla")'},
{:python3 => ' print("{0!r}".format(bla)) # comment',
:python2 => ' print "{0!r}".format(bla) # comment'},
{:python3 => ' print("{0!r}".format(bla, bla)) # comment',
:python2 => ' print "{0!r}".format(bla, bla) # comment'},
{:python3 => ' print("%r" % (bla, bla)) # comment',
:python2 => ' print "%r" % (bla, bla) # comment'},
{:python3 => ' print(variable) # comment',
:python2 => ' print(variable) # comment'},
{:python3 => ' print(variable) # comment',
:python2 => ' print variable # comment'},
{:python3 => ' print("""{0}
bla
bla""".format("bla")) # comment',
:python2 => ' print """{0}
bla
bla""".format("bla") # comment'},
{:python3 => ' print("""
bla
bla""") # comment',
:python2 => ' print """
bla
bla""" # comment'},
{:python3 => ' print("""%s
bla
bla""" % (bla, bla)) # comment',
:python2 => ' print """%s
bla
bla""" % (bla, bla) # comment'}
]
pairs.each do |pair|
assert_equal(pair[:python3], convert_to_py3k_print(pair[:python2]))
end
end
def test_convert_from_py3k_print
pairs = [
{:python3 => 'print("bla bla", file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla bla"'},
{:python3 => 'print("bla bla".upper(), file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla bla".upper()'},
{:python3 => 'print("bla %s" % ("bla"), file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla %s" % ("bla")'},
{:python3 => 'print("bla bla".upper(), file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla bla".upper()'},
{:python3 => 'print("bla %s" % ("bla"), file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla %s" % ("bla")'},
{:python3 => 'print("bla %s" % "bla", file=sys.stdout)',
:python2 => 'print >> sys.stdout, "bla %s" % "bla"'},
{:python3 => 'print("bla %s" % "bla", file=sys.stdout) # comment',
:python2 => 'print >> sys.stdout, "bla %s" % "bla" # comment'},
{:python3 => 'print("%r" % adapter)',
:python2 => 'print "%r" % adapter'},
{:python3 => 'print("{0!r}".format("bla"))',
:python2 => 'print "{0!r}".format("bla")'},
{:python3 => ' print("{0!r}".format(bla)) # comment',
:python2 => ' print "{0!r}".format(bla) # comment'},
{:python3 => ' print("{0!r}".format(bla, bla)) # comment',
:python2 => ' print "{0!r}".format(bla, bla) # comment'},
{:python3 => ' print("%r" % (bla, bla)) # comment',
:python2 => ' print "%r" % (bla, bla) # comment'},
{:python3 => ' print(variable) # comment',
:python2 => ' print variable # comment'},
{:python3 => ' print(variable) # comment',
:python2 => ' print variable # comment'},
{:python3 => ' print("""{0}
bla
bla""".format("bla")) # comment',
:python2 => ' print """{0}
bla
bla""".format("bla") # comment'},
{:python3 => ' print("""
bla
bla""") # comment',
:python2 => ' print """
bla
bla""" # comment'},
{:python3 => ' print("""%s
bla
bla""" % (bla, bla)) # comment',
:python2 => ' print """%s
bla
bla""" % (bla, bla) # comment'},
{:python3 => 'print("Mode is %r and file already has %r, skipping..." %
(self.mapfile.mode, k))',
:python2 => 'print "Mode is %r and file already has %r, skipping..." % \
(self.mapfile.mode, k)'},
{:python3 => 'print("Mode is %r and file already has %r, skipping..." % # comment
(self.mapfile.mode, k))',
:python2 => 'print "Mode is %r and file already has %r, skipping..." % \
(self.mapfile.mode, k) # comment'}
]
pairs.each do |pair|
assert_equal(pair[:python2], convert_from_py3k_print(pair[:python3]))
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment