简体   繁体   中英

Python - How to run code written for new version on legacy interpreter?

EDIT: Finally I did it, but complete process was pain in the ass and for future development I will definitively listen to @Martijn Pieters advises

I am python newbie and need to transfer some Python project which I did on Windows (cygwin) machine to Linux. The project uses ipaddress module. I have no root access nor internet access from Linux machine, so installing anything is not possible. So I have copied to one Linux folder both my project file (ipfind_v5.py) along with ipaddress.py module which I found under cygwin's /lib/python2.7/site-packages directory. The problem is that when I issue the script I get following error:

[wakatana@zeus]$ python ipfind_v5.py
Traceback (most recent call last):
  File "ipfind_v5.py", line 28, in ?
    import ipaddress as IP
  File "/home/wakatana/ipfind.py/ipaddress.py", line 28
    if b'\0'[0] == 0:  # Python 3 semantics
           ^
SyntaxError: invalid syntax

I have replaced

if b'\0'[0] == 0:

with

if '\x00' == 0:

But then another error occurred:

[wakatana@zeus ipfind.py]$ python ipfind_v5.py
Traceback (most recent call last):
  File "ipfind_v5.py", line 28, in ?
    import ipaddress as IP
  File "/home/wakatana/ipfind.py/ipaddress.py", line 1123
    except ValueError as exc:
                       ^
SyntaxError: invalid syntax

Then based on this https://docs.python.org/2/tutorial/errors.html article about exceptions, I did:

sed -i 's/ as exc/, exc/' ipaddress.py

After this I get another error (source of ipaddress module is here: https://github.com/phihag/ipaddress/blob/master/ipaddress.py ):

[wakatana@zeus ipfind.py]$ python ipfind_v5.py
Traceback (most recent call last):
  File "ipfind_v5.py", line 28, in ?
    import ipaddress as IP
  File "/home/wakatana/ipfind.py/ipaddress.py", line 1173
    if isinstance(b, bytes)
     ^
SyntaxError: invalid syntax

Then I rewrite this part:

return u'.'.join(_compat_str(struct.unpack('!B', b)[0]
                             if isinstance(b, bytes)
                             else b)
                 for b in _compat_to_bytes(ip_int, 4, 'big'))

Into this (hope this is uquivalents, seems that code is running OK):

retval=[]
for b in _compat_to_bytes(ip_int, 4, 'big'):
  if isinstance(b, str):
    retval.append(_compat_str(struct.unpack('!B', b)[0]))
  else:
    retval.append(b);

return unicode(".".join(retval))

Another two steps which was needed: changing bytes to str changing: from . import foo to: import foo

Configuration:

Linux version: Python 2.4.3

Windows (cygwin) version: Python 2.7.3

You cannot make Python 2.4 run Python 2.7 code, no.

The Python project follows the semantic version model using a MAJOR.MINOR.PATCH numbering scheme. Python guarantees that syntax will work unchanged across patch versions; 2.4 code works correctly across 2.4.x releases, barring bugs. Across minor versions, Python tries to maintain backwards compatibility ; code from earlier 2.x releases continue to work on later releases insofar possible. Thus, code written for 2.4 still works when run with Python 2.7. Python 3 is a new major release cycle and introduced major backwards incompatible changes.

The change from except Exception, name: to except Exception as name: is one such change, introduced in Python 2.6 ; the old syntax was error-prone, the newer syntax makes it clearer you are binding the caught exception to a name.

That said, efforts have been made to make it easier to write code that can run on both Python 2.x and Python 3.x interpreters. This included making additions in Python 2.x releases to accept certain types of syntax that would otherwise only work in Python 3.

The b'...' syntax is one such change. The Python 2 str type has been replaced by the bytes type in Python 3, and the b'..' notation is the bytes string literal syntax. Because bytes effectively are the old str type in Python 2, you can use b'...' from Python 2.6 onwards as well, resulting in a regular Python 2 string object. Conversely, newer Python 3.x releases accept u'...' as string literal syntax, which in Python 2 would have resulted in a Unicode string value.

Each major and minor release documents what changed and what is new in the What's new section , you'll have to read through those documents if you want to back-port code to Python 2.4.

There is no 'universal converter' for this. There is a tool to convert between Python 2 and Python 3 syntax (see the 2to3 and 3to2 tools), but these won't help you packport 2.7-compatible code to 2.4.

It is, however, relatively easy to compile a Python interpreter and install it in your home directory, without root access. I'd download Python 2.7, configure it with ./configure --prefix=$HOME , then make , make install to have it installed in ~/bin/ and ~/lib/python2.7/ , and run the script with that binary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM