Skip to content

Python 2/3 Compatibility - #500

Merged
sangjinhan merged 11 commits into
masterfrom
2to3
Jun 7, 2017
Merged

Python 2/3 Compatibility#500
sangjinhan merged 11 commits into
masterfrom
2to3

Conversation

@changlan

@changlan changlan commented Jun 5, 2017

Copy link
Copy Markdown
Member

This should fix #488.

  • Modified Python code to be 2/3 compatible
    • Use Python 3 style print() with from __future__ import print_function;
    • Use list comprehension instead of map and filter;
    • Use items() instead of iteritems() (Yeah, it would become less efficient in Python 2);
    • Use io package to read() from files, so that the resulting string is Unicode-encoded;
    • Use raw_input for Python 2 and input for Python 3;
    • Disable implicit relative import and use absolute import instead;
    • Fix the discrepancy of tokenizer between Python 2/3 (-> is an OP token in Python 3);
    • Run 2to3 over protoc generated scripts, since those scripts still use implicit relative import;
    • Use raw bytes for non-Unicode literals (e.g b'\x01').
  • Add unit test for both Python 2/3.

@changlan
changlan force-pushed the 2to3 branch 2 times, most recently from 5aa2591 to 82e6ddf Compare June 5, 2017 21:55
@codecov

codecov Bot commented Jun 5, 2017

Copy link
Copy Markdown

Codecov Report

Merging #500 into master will increase coverage by <1%.
The diff coverage is 77%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #500    +/-   ##
=======================================
+ Coverage      64%     64%   +<1%     
=======================================
  Files         198     198            
  Lines       12071   12079     +8     
=======================================
+ Hits         7766    7772     +6     
- Misses       4305    4307     +2
Impacted Files Coverage Δ
pybess/protobuf_to_dict.py 56% <ø> (ø) ⬆️
pybess/module_msg.py 100% <100%> (ø) ⬆️
bessctl/test_samples.py 90% <100%> (ø) ⬆️
bessctl/test_sugar.py 97% <100%> (ø) ⬆️
pybess/test_protobuf_to_dict.py 100% <100%> (ø) ⬆️
pybess/test_bess.py 100% <100%> (ø) ⬆️
pybess/bess.py 40% <47%> (ø) ⬆️
bessctl/sugar.py 92% <91%> (-1%) ⬇️
core/utils/checksum_test.cc 99% <0%> (-1%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b75a71a...3b2bd70. Read the comment docs.

Comment thread bessctl/bessctl Outdated
@@ -1,24 +1,25 @@
#!/usr/bin/env python2.7

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now all scripts should start with "#!/usr/bin/env python", so that they can run regardless of the installed Python version..?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(sorry not all scripts, but executable scripts)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread .travis.yml Outdated

install:
- sudo apt-get install -y python
- sudo apt-get install -y python python3 python3-pip

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it is not an issue on our test setup, python might be an alias of python3 on other distros. I would be better to specify python2 explicitly.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. python2 is not a package name, but I changed python to python2 in other places.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

python2.7...?

@changlan changlan Jun 6, 2017

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... Done -_-||

Comment thread .travis.yml Outdated
install:
- sudo apt-get install -y python
- sudo apt-get install -y python python3 python3-pip
- pip install grpcio scapy codecov

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pip2

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread .travis.yml Outdated
- sudo apt-get install -y python
- sudo apt-get install -y python python3 python3-pip
- pip install grpcio scapy codecov
- pip3 install grpcio coverage

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(why not scapy for pip3?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scapy for pip3 is broken :(
And the tests don't need scapy.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh... then perhaps scapy-python3 is the package we need to install (https://github.com/phaethon/scapy)...

Also bessctl/bessctl -- daemon start -- run testing/run_module_tests in .travis.yml now needs "python2" explicitly, as it does use scapy?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we would need to replace str(scapy packet) with bytes(scapy packets) in BESS scripts... The scapy3k webpage says:

N.B.! As a difference from scapy for python2, use bytes() instead of str() when converting packet to bytes. Also, most arguments expect bytes value instead of str value except the ones, which are naturally suited for human input (e.g. domain name).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread bessctl/bessctl Outdated
@@ -1,24 +1,25 @@
#!/usr/bin/env python2.7

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(sorry not all scripts, but executable scripts)

Comment thread bessctl/bessctl Outdated
line_buf = []

for arg in sys.argv[1:]:
arg = arg.decode()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we convert it into a unicode..? (please add a comment)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StringIO takes unicodes. I changed it to BytesIO for clarity (and thus avoiding the conversion).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it seems that in Python 2 arguments are merely str (not unicode), while in Python 3 they are Unicode str, so we have to convert them into unicode first.

@chris3torek chris3torek Jun 6, 2017

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

py3k str is Unicode, yes. (The type name unicode no longer exists, it's all just str.) py2k str and bytes are the same underlying type. The py2k io.StringIO does require unicode, so probably this should use io.BytesIO on py2k and io.StringIO on py3k. Or you can use six.StringIO here, if you're importing six (I forget if you are).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I guess it is easier to just make sure the input are Unicode (already did) instead of handling StringIO and BytesIO separately. I am attempting to avoid extra packages like six and future to keep the dependency minimal 😄

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but you'll have to not do .decode() if it's py3k (either that, or trap AttributeError as there is no decode for str objects).

@changlan changlan Jun 6, 2017

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has been fixed in 5e4a82d

@chris3torek chris3torek Jun 6, 2017

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, clever! u' '.join(...) works in both, converting py2k string-as-bytes to unicode, leaving py3k strings alone.

Comment thread pybess/protobuf_to_dict.py Outdated
FieldDescriptor.TYPE_BOOL: bool,
FieldDescriptor.TYPE_STRING: unicode,
FieldDescriptor.TYPE_STRING: str,
FieldDescriptor.TYPE_BYTES: str,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not quite sure about this, but shouldn't it be bytes...?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@chris3torek chris3torek left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've merely scanned this for anything that stood out to me.

Comment thread bessctl/bessctl Outdated
line_buf = []

for arg in sys.argv[1:]:
arg = arg.decode()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The elements of sys.argv should already be strings (not bytes) in py3k. Are you sure this is needed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explained in @sangjinhan's comment above.

Comment thread build.py Outdated
@@ -111,7 +112,7 @@ def check_c_lib(lib):
def required(header_file, lib_name, compiler):
if not check_header(header_file, compiler):
print >> sys.stderr, 'Error - #include <%s> failed. ' \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be missing its conversion...?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this seems to be a stale version.

Comment thread container_build.py Outdated
@@ -73,9 +74,9 @@ def do_dist_clean():

def print_usage():
print >> sys.stderr, \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also still has the >> sys.stderr (and is not a function call)...

FieldDescriptor.TYPE_SFIXED64: long,
FieldDescriptor.TYPE_SFIXED64: int,
FieldDescriptor.TYPE_BOOL: bool,
FieldDescriptor.TYPE_STRING: unicode,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand how this is to work in both py2k and py3k but I also don't quite understand how it works now in py2k in the first place, so I'm just confessing ignorance here. 😄 (In particular the values have to already have been converted somewhere by this point.)

@changlan
changlan force-pushed the 2to3 branch 3 times, most recently from 5353b8d to 5e7fc4a Compare June 6, 2017 00:39
@sangjinhan

Copy link
Copy Markdown
Member

tumblr_laq3zzq8ph1qe2yaso1_500

@changlan
changlan deleted the 2to3 branch June 7, 2017 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Installing BESS on working system with grpc and python3 fails

4 participants