How to call 2to3 before run py2app - python-3.x

I have a setup.py that use py2app, and I want to run 2to3 to convert python script to Python 3 compatible before build the app. I used option setup(use_2to3=True), but it did not call 2to3. So now I use a Makefile to work around this problem. Any pythonic solution? The setup.py is below. Please help.
import sys
from setuptools import setup
from plistlib import Plist
plist = Plist.fromFile('Info.plist')
OPTIONS = {
'iconfile': 'python.icns',
'plist': plist
}
if sys.version_info.major < 3:
app = "PyInterpreter.py"
else:
app = "build/PyInterpreter.py"
setup(
name="PyInterpreter",
app=[app],
data_files=["English.lproj"],
options={'py2app': OPTIONS},
setup_requires=["py2app"],
use_2to3=True,
)
Thanks.

py2app does not support use_2to3, and likely never will unless someone contributes a patch (I'm the maintainer of py2app).
The cleanest solution to use 2to3 is to call it yourself, for example in a custom distutils command that subclasses py2app.build_app.py2app (implement a run method that calls 2to3, possibly adjust the build environment, then call the py2app.run method).
It is often much nicer to not use 2to3, but convert the code to something that runs with both python 3 and python 2. That's fairly easy when you can drop support for python 2.5 (and more so when you only need to support 2.7 or later), as most of the syntax of python 3 is supported in 2.6.
BTW. plistlib.Plist.fromFile is deprecated, use plistlib.readPlist instead.

Related

How do tell "swig -python -py3 myswig.i" not to include annotations

I need to use SWIG to support both Python 2.7 and Python 3.10. [Yes, I know that Python 2.7 is dead, and we're doing our best to migrate users away from it as quickly as we can.]
I generate my module via setuptools.setup with a Swig extension. I can run the setup using both Python2 and Python3. The setuptools program creates a separate shareable library for the Python2 and Python3 runs. However both runs generate a myswig.py file in the same location.
It turns out that the Py2 and Py3 generated files are identical, except that the Py3 generated file contains annotations for the functions and the Py2 doesn't. Python3 can read the Python2 generated file and works just fine. Python2 cannot read the Python3 generated file.
I've tried both %feature("autodoc", 0); and leaving out this line completely, and I still get annotations.
So is there someway of either:
Turning off annotations in the generated file
Adding from __future__ import annotations automatically to the generated file
Don't use -py3. It's not required for Python 3, but enables Python 3-specific code features like annotations.

How to use Ned Batchelder's script for McCabe's Complexity programmatically?

I'm trying to use Ned Batchelder's script for McCabe Complexity to get the complexity of codes written in Python 3, but I want to run it from a script instead of running it via command line.
I've already installed the McCabe from pypi and the version is 0.6.1. I'm using Python 3.8 in VSCode via Jupyter Notebook.
After reading mccabe.py from the GitHub page, I'm trying this so far:
from mccabe import *
code = open("testFile.py").read()
res = get_code_complexity(code, threshold=7, filename="testFile.py")
print(res)
However, the result I'm getting from the code above is this:
testFile.py:5:1: C901 'If 5' is too complex (63)
1
I don't know how to interpret this, because when I run the application from the command line, I get this:
$ python -m mccabe testFile.py
If 5 63
What does this mean? I thought that the complexity would be this 63, but in the res variable I'm getting 1 returned. testFile.py is in the same directory I'm running the .ipynb. I uploaded it as I think it may help.
P.S.: I know I could use Radon for this, but it seems that it only calculates the McCabe Complexity if the code is within a function, not "loose". The vast majority of the programs I'm trying to analyze don't use main(). The testFile.py I'm using as an example results in a blank list when using Radon, that's why I'm trying with this McCabe from Ned Batchelder.

Is it possible to install python libraries with pip programmatically?

Let me explain what I want to do.
The list of libraries I want installed is listed in a .txt file.
My script reads the list from the file sequentially, and if the script isn't installed, it installs it via pip, or if it is already installed, checks the version and updates it if necessary.
I googled it up but didn't find how to do that. Can you offer any help or guidance?
Yes you can. Try this, here is an example of one module which is hard coded
import os
import subprocess
import sys
get_pckg = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
installed_packages = [r.decode().split('==')[0] for r in get_pckg.split()]
required_packeges = ['shopifyAPI'] // Make a change here to fetch from file
for packg in required_packeges:
if packg in installed_packages:
pass
else:
print('installing package')
os.system('pip install ' + packg)
First i will fetch all installed modules and then i will check my required module is installed or not if not then it will install it.
Yes, you can. Python module os does support running script programmatically. Since I don't know how your file structure looks like, I guess you can read the file and run the script sequentially.
import os
os.system("pip install <module>")
Use Following to install lib. programmatically.
import pip
try:
pip.main(["install", "pandas"])
except SystemExit as e:
pass

can't import http in python 3.5.1 but it works in cmd

I'm still learning python. I have windows 8 and had downloaded 2.7 as well as 3.5 because two modules I used in the past respectively used different python versions. Now though, I'm trying to run a script where the first line is import http.client or http. Neither of these work though. In cmd, python returns 3.5.1 currently and import http.client and import http return with no errors but in my IDE these don't work. Why not?
You can follow the Pycharm documentation here to change the Python version for your project from Python 2 to Python 3.
(In particular, Selecting Python interpreter for a project section)

How can I make my script choose the right python interperter?

I have both 2.7 and 3.0 versions of the Python interpreter installed (on my Ubuntu 32 system), but one particular script uses 3.0.
Using
#!/usr/bin/python3 -B
will not work when the program is run with python myprogram.py.
And I also need a solution that works also in Windows where I also have both python versions installed.
How can I make the script to run only with the right python version?
Please use virtualenv, which makes isolated Python environments easy.
python = Python to use. # This has to be the absolute path to Python executable
os.execl(python, python, * sys.argv)
This way you can restart the script with the python you want to use. Not really stylish.
I don't know why you can't just launch the program with python3 foo.py, but it's possible to have a python2 program relaunch itself as python3 with something like this.
import sys
if sys.version_info.major != 3:
import os
# replace this process with a python3 process
os.execlp("python3", "python3", *sys.argv)
It's a bad solution though, because now your python3 program can't use anything that's not valid python2 syntax
Please take a look at The wrong python interpreter is called
You have to choose a correct interpreter based on where you installed the desired version of Python and your system variables.

Resources