Skip to content

Conversation

@eli-schwartz
Copy link

This patch series implements an incremental move to python3 in the nmap codebase. All changes should continue to work in python2, but improve the compatibility with python3.

Currently, I've mostly upgraded old-style python2 code that does not work on python3, to new-style python2 code that also works on python3; these changes are "the correct way" to do something on both python2 and python3, and thus have value even in an exclusively python2 codebase (but obviously python3 is important. ;))

The last patch adds additional compatibility shims only needed on python3 by using https://pypi.org/project/six/. Once python3 support is complete and python2 is dropped, six.* imports can be converted to their canonical python3 representations instead.

@eli-schwartz
Copy link
Author

Ping. Any update on merging this?

@fyodor
Copy link
Member

fyodor commented Jun 10, 2020

Hi @eli-schwartz . Thanks for the patch. I just made a note of it in issue #1176 . Have you been able to successfully use Zenmap on a python3-only system with this patch? I was under the impression that we would need a more fundamental overhaul because I thought some of our libraries (pygtk in particular, if I recall) wouldn't work with Python3.

But it's a terrible way to discover if something exists, anyway (e.g.
empty strings evaluate false), so let's switch to something simpler.

NmapOptions already imported functools.reduce, but this is once again an
overly complicated way to detect the existence of an option.
The code still runs under python2, but, where trivially possible,
python2-only code is converted to code that runs on both python2 and
python3.

Changes made with the command:

find . -name \*.py -exec python-modernize --no-six -wn {} +
It's available since python 2.1 and cmp is considered inferior to use in
python2 and totally removed in python3.

For Gtk ListStore sort functions that need a cmp interface, implement cmp
manually as (a > b) - (a < b)
Note: get_addrs must always return a list, since on python3 you cannot
compare a Nonetype to a list. An empty list will always compare < a list
with something in it, which was the python2 behavior when comparing to
None.
@eli-schwartz eli-schwartz force-pushed the master branch 2 times, most recently from 8f24d0b to 89a3a1e Compare June 10, 2020 06:52
@eli-schwartz
Copy link
Author

I haven't tried running it in python3 yet, but I'm a big believer in baby steps. :)

First things first, let's get the codebase into a healthy place where hopefully the only thing that is left to port is pygtk usage itself.

I've revised my patch series, by the way, adding some more future imports and fixing a division error that cropped up as a result. I can run or load scans on python2, so it should work as is.

Also ff357f9 is just weird and broken right now.

We explicitly rely on this not being a float. Use modern idiom which
works on python2 and python3.
We want to print

assuming "unknown".

like we do in other parts of the file too. But for some reason, it was

assuming \unknown\.

Which is strange, and also fails to compile on python3, or python2 with
unicode_literals, because \unknown isn't a valid unicode \uXXXX escape.

This was broken in commit da0c947 which
changed u"assuming \"unknown\"." to u'assuming \unknown\.' with single
quotes, but dropped the quotes instead of the escapes.
@eli-schwartz
Copy link
Author

eli-schwartz commented Jun 12, 2020

Partially rolled back the unicode_literals change as I found more places where pygtk is oddly finicky about using the native str() type. The main identified benefit of unicode_literals in this codebase was making io.StringIO work nicely... pygtk strings will need to fend for themselves for now, hopefully they don't have broken escapes like the ndiff line.

absolute_import and print_function are kind of no-brainers

division seems safe as there don't seem to be many violations of such,
and if there are, it is broken and needs to be fixed. Some errors have
been caught by enforcing this on python2 as well.

unicode_literals is usually safe, but some things were excluded due to
restrictions on needing str() itself. Specifically, pygtk is very picky.
Rather than manually casting many strings back to str(), these files are
simply excluded for now.
The io module was introduced in python 2.6 and in python 3.x fully replaces the
cStringIO/StringIO modules from python 2.x, which are no longer
available.

It is mostly a drop-in replacement, with the caveat that io.StringIO and
io.BytesIO are not interchangeable due to python3 separating the str and
bytes types, but the nmap usage is restricted to manipulating files as
text, so it should work as-is.
Add additional fixes which rely on the python-six module.

Changes made with the command:

find . -name \*.py -exec python-modernize -wn {} +

manual fixup of gettext.install, which takes a unicode= parameter, but
only on python2.
cclauss added a commit to cclauss/nmap that referenced this pull request Nov 7, 2022
Prove the Python syntax errors as discussed in
* nmap#91
* nmap#342
* nmap#624
* nmap#665
* nmap#666
* nmap#1176
* nmap#1484
* nmap#1807
* nmap#1972
* nmap#2088 
* nmap#2279
* nmap#2287
* nmap#2446
* nmap#2493
* nmap#2522
And many more...
cclauss added a commit to cclauss/nmap that referenced this pull request Nov 7, 2022
Prove the Python syntax errors as discussed in
* nmap#91
* nmap#342
* nmap#624
* nmap#665
* nmap#666
* nmap#1176
* nmap#1484
* nmap#1807
* nmap#1972
* nmap#2088 
* nmap#2279
* nmap#2287
* nmap#2446
* nmap#2493
* nmap#2522
And many more...
@nmap-bot nmap-bot closed this in 37dd096 Dec 15, 2022
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.

2 participants