#2 Open
Repository
kmike kmike
Branch
default
Repository
robertkern robertkern
Branch
default

Python 2.6-3.3 compatibility (using a single codebase approach)

Bitbucket cannot automatically merge this request due to conflicts.

Review the conflicts on the Overview tab. You can then either decline the request or merge it manually on your local system using the following commands:

hg update 
hg pull -r default https://bitbucket.org/kmike/line_profiler
Author
  1. Mikhail Korobov avatarMikhail Korobov
Reviewers
Description

Hi Robert,

I added Python 3.x compatibility to line_profiler using a single codebase approach - line_profiler should work under Pythons 2.6, 2.7, 3.2 and 3.3.

Unfortunately there are no tests, but what I checked works, and the fixes are IMHO straightforward.

What I checked manually:

  • %lprun IPython magic under Python 2.7 and 3.3 with functions;
  • %lprun IPython magic under Python 2.7 with generators;
  • %lprun IPython magic under Python 2.7 and 3.3 with invalid -f argument

What do you think? I would be great to see Python 3.x-compatible line_profiler on pypi! :)

Comments (14)

  1. Robert Kern repo owner

    I think this is a perfect reason to drop Python 2.5. Thanks!

    We can also drop the exec workaround to for supporting PEP 342 generators.

  2. Mikhail Korobov author

    kernprof.py works for me now.

    kernprof.py -b flag doesn't work though, but this seems unrelated to Python 3.x support (it fails even without my changes). The exception is:

    Traceback (most recent call last):
      File "/Users/kmike/envs/pymorphy/bin/kernprof.py", line 233, in <module>
        sys.exit(main(sys.argv))
      File "/Users/kmike/envs/pymorphy/bin/kernprof.py", line 230, in main
        prof.print_stats()
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/cProfile.py", line 81, in print_stats
        pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pstats.py", line 93, in __init__
        self.init(arg)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pstats.py", line 107, in init
        self.load_stats(arg)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pstats.py", line 136, in load_stats
        self.__class__, arg)
    TypeError: Cannot create or construct a <class pstats.Stats at 0x1041f1f58> object from '<__main__.ContextualProfile object at 0x1041da910>''
    

    It is raised when there are not functions decorated with @profile.

    If cProfile import is commented out, then ContextualProfile.__init__ fails because profile.Profile is an old-style class and thus super() doesn't work. After changing it to use Profile.__init__ exception is no longer raised. But it seems we don't need to fix this because cProfile is always imported under 2.x, and under 3.x super always work.

  3. Mikhail Korobov author

    I think the pull request is ready. It seems that more code may be dropped from Cython extension because of removal of 2.5 support, but I don't want to make this pull request more complex.

  4. Mikhail Korobov author

    I'm using it since March too, without issues in both 2.x and 3.x virtualenvs.

    I guess merging is hard mainly because line_profiler is very stable software, there are no unit tests for this PR, and the changes are non-trivial, esp. if one haven't done Python 3.x porting before, so it is hard to check if this PR is valid. Also, after merging Robert should commit himself to supporting Python 3 in line_profiler and check patches for Python 3.x compatibility. I don't know how to improve the situation - writing proper tests for line_profiler looks quite hard, and unfortunately I don't have time for that now.

    What I can do is to offer help with fixing compatibility issues after merging this PR - say, I'll submit a PR with a fix for any Python 2.x or 3.x compat issue in a period of 14 days after raising it for all issues raised until 2015 :)

  5. gregcouch

    Since in line_profiler.py the "print message," can't be converted to "print(message, end=)" and retain Python 2 compatibility, should the subsequent leading \n's should be dropped?

  6. Mikhail Korobov author

    There are two "\n"s (for dump_file and text_file), and the second "\n" may be either between the message and "text_file" or between "dump_file" and "text_file", so if we just remove these "\n"s we'll lose one separator when both options are ON.

    Does strict backwards compatibility matter in this case? I found extra empty line nice :)

  7. Mikhail Korobov author

    I've fixed an issue with extra newline as Joseph Martinot-Lagarde suggested. It looked well in IPython notebook, but not so well when line_profiler is used in a regular IPython shell. I prefer not to fix PY2/PY3 thing to keep the relevant code 1-to-1 copy-paste from six.

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.