embed python environment in c++ application - python

Using the c-python api I try to embed python 3.6 into a c++ application.
However instead of using the system install i'd like to use a virtual environment.
I didn't find any documentation on the way to do that.
Some related documentation mention
py_SetProgramName
or
py_SetPythonHome
Also when reading c-python code i can see the use of pvenv.cfg or ._pth files, but none of these solution seem to work.
Any idea what's the right way to use virtual environment from c api?
EDIT
Let's take a concrete example. I have python installed in
c:\python36
For my c++ application I created a virtual env using the command python -m venv c:\my_cpp_app\python_venv\ in:
c:\my_cpp_app\python_venv\
Using the c-python api I'd like to make my cpp application use the virtual environment located in python_venv instead of c:\python36\

As stated in comments, embedded python 3.6 and virtual environment created with venv seem incompatible (bugs.python.org/issue22213)
I managed to make it work using virtualenv instead and by calling Py_SetPythonHome prior Py_Initialize.
See more details on the python startup sequence
Locating Python and the standard library
The location of the Python
binary and the standard library is influenced by several elements. The
algorithm used to perform the calculation is not documented anywhere
other than in the source code. Even that description is
incomplete, as it failed to be updated for the virtual environment
support added in Python 3.3 (detailed in PEP 405).
These calculations
are affected by the following function calls (made prior to calling
Py_Initialize()) and environment variables:
Py_SetPythonHome()
Py_SetProgramName()
PYTHONHOME
The filesystem is also inspected for
pyvenv.cfg files (see PEP 405) or, failing that, a lib/os.py (Windows)
or lib/python$VERSION/os.py file.
The build time settings for PREFIX
and EXEC_PREFIX are also relevant, as are some registry settings on
Windows. The hardcoded fallbacks are based on the layout of the
CPython source tree and build output when working in a source
checkout.
The implementation of pep 587 in later versions should facilitate all this!

Related

How do I install Gimp-Python on windows?

I try to write a simple plugin with gimpfu in python and I tried following those instructions.
1.2. Installation
Gimp-python consists of a Python module written in C and some native python support modules. You can build pygimp with the commands:
./configure
make
make install
This will build and install gimpmodule and its supporting modules, and install the sample plugins in gimp's plugin directory.
Where do I have to execute those commands?
I tried adding my script to the plugins folder but it seems like there is no python module called gimpfu. I believe I have to enable or install it in some way, but I can't find a solutio to do it.
EDIT: It seems like gimpfu is availible in the gimpfy-console insode gimp. It just doesn't seem to be availible for my plugin scripts.
No need to install anything. In the Windows versions Python support is built-in, and the gimpfu import is available when your code is executed by Gimp.
If you don't see the plugin in the menu it is likely a syntax error that doesn't let it run its registration code. See here for some debugging techniques.
However, since you mention PyCharm, you may have another Python interpreter installed and this makes things complicated because there can be conflicts depending on order of installation (and remember, Gimp uses Python 2.7)
Now it all depends if you are really doing a plugin (called from the Gimp menu) or a batch (where Gimp is called from a shell script), which is somewhat different. If you are writing a batch, see this answer for an example.
you don't need to install anything, on windows gimp comes with a python interpreter along with the libraries inside of it.
if you want to run your script from inside GIMP then you should check this answer and you should add the path to gimp to your system PATH environment variable (which is C:\Program Files\GIMP 2\bin on my system) , and instead of calling gimp-console.exe you should replace that with whatever gimp-console is currently available in that folder, the one on my system is gimp-console-2.10.exe.

Should we gitignore the .python-version file?

I have a .python-version file, and when I create a Python repo with github and specify that it should have a .gitignore, it adds the .python-version file to it. It seems to me that that file should NOT be ignored since other people running the code on different machines would want to know what version of Python they need.
So why is it .gitignored?
While being too specific, you can still version that file (meaning: not include it in the default .gitignore), as :
it will be used only by pyenv
it is a good addition to the README, in order to illustrate what version of python is recommended for the specific project,
it can be overridden easily (if you are using pyenv), or simply ignored (if you don't have pyenv).
As the article "How to manage multiple Python versions and virtual environments " states:
When setting up a new project that is to use Python 3.6.4 then pyenv local 3.6.4 would be ran in its root directory.
This would both set the version, and create a .python-version file, so that other contributors’ machines would pick it up.
But:
pyenv looks in four places to decide which version of Python to use, in priority order:
The PYENV_VERSION environment variable (if specified).
You can use the pyenv shell command to set this environment variable in your current shell session.
The application-specific .python-version file in the current directory (if present).
You can modify the current directory's .python-version file with the pyenv local command.
The first .python-version file found (if any) by searching each parent directory, until reaching the root of your filesystem.
The global version file. You can modify this file using the pyenv global command.
If the global version file is not present, pyenv assumes you want to use the "system" Python. (In other words, whatever version would run if pyenv weren't in your PATH.)
The reason why .python-version should be gitignored is because its version is too specific. Tiny versions of Python (e.g. 2.7.1 vs 2.7.2) are generally compatible with each other, so you don't want to lock down to a specific tiny version. Furthermore, many Python apps or libraries should work with a range of Python versions, not just a specific one. Using .python-version indicates that you want other developers to use an exact, specific Python version, which is usually not a good idea.
If you want to indicate the minimum Python version needed, or otherwise a version range, then I believe documenting that in a README is a more appropriate solution.
It can also be a bit problematic when using python virtual environments, as people may want to use virtual environment names different than 3.7.2/envs/myvenv.
Old post but still relevant.
My answer would be "it depends".
The name of a virtual env can also be used in .python-version, if it is managed with the help of the virtualenv plugin of pyenv. This makes this file pretty useless it the project is managed on a public Git repo and you can exclude it (but not to do is harmless as told in other answers).
But (and I am in this situation) if you manage the project on a private repo and share virtual envs, it can make sense to not exclude it from Git. This allows you to work with a different environment (including the Python version) on an experimental branch of the project. Of course, it would have been far cleaner to fork or clone the original project and experiment with the new env in the copy, but sometimes it easier to just create a new branch.
At the end of the day, IMHO there is no universal answer to the question, and it depends on your workflow.
Well sir I think answer to your question is YES. I just openend GitHub official repo and checked the project gitignore.
It showed .python-version file mentioned there.
And if it's not getting ignored you can simply check for correct way to mention.

Managing two versions of Python on the same PC

I have a Windows PC and am running Python 3.4 for some time with all my code using this version. C:\Python34 and C:\Python34\Scripts are on my search path.
I want to use Google App Engine now but it seems that I will have to install Python 2.7.
I have no problems managing both versions manually for my own programs. But how about applications that run behind my back or under the covers, eg GAE, pip, etc? How would they know which or where the correct version will be?
Specifically, for GAE, can I continue to have Python 3.4 as the one with the option "Make this the Python installation the default Python installation"?
For this purpose exists a "virtualenv" tool alias virtual enviroment. More HERE.
In short, you create a container (folder/enviroment) "A" with version 2.X and another container "B" with version 3.X and inside these containers will be all scripts executed by appropriate python interpreter which you have selected during creating these containers.
Official documentation of virtualenv is aimed to UNIX/Linux systems, so for you as WIN's user might be better (easier) to use "virtualenvwrapper-win". More HERE
Change the Paths in system control panel
Or set PATH value in cmd line before running 3PP programs

What is the use of the path /usr/share/pyshared in python?

I found that some applications developed with python drop their files in this path, what is the use of this path, and what files should I put in it ?
That directory includes architecture-independent python modules that can be shared by multiple python version. Do not manipulate that directory.
See Debian Python Policy Chapter 1 - Python Packaging
Take a look at the Debian python policy.
1.5 Module Path
By default, Python modules are searched in the directories listed in
the PYTHONPATH environment variable and in the sys.path Python
variable. Since python2.4 version 2.4.5-3, python2.5 version 2.5.2-7,
python2.6 version 2.6.2-1, and in all python2.7 versions, sys.path
does not include a /usr/lib/pythonXY.zip entry anymore. Directories
with private Python modules must be absent from the sys.path. Public
Python modules not handled by python-central or python-support must be
installed in the system Python modules directory,
/usr/lib/pythonX.Y/dist-packages for python2.6 and later, and
/usr/lib/pythonX.Y/site-packages for python2.5 and earlier. Public
Python 3 modules must be installed in /usr/lib/python3/dist-packages.
Modules managed by python-support are installed in another directory
which is added to the sys.path using the .pth mechanism. The .pth
mechanism is documented in the Python documentation of the site
module. A special directory is dedicated to public Python modules
installed by the local administrator, /usr/lib/python3/dist-packages
for all python3 versions, /usr/local/lib/python2.Y/dist-packages for
python2.6 and later, and /usr/local/lib/python2.Y/site-packages for
python2.5 and earlier. For a local installation by the administrator
of python2.6 and later, a special directory is reserved to Python
modules which should only be available to this Python,
/usr/local/lib/python2.Y/site-packages (and
/usr/local/lib/python3/site-packages for all python3 versions).
Unfortunately, for python2.5 and earlier this directory is also
visible to the system Python. Additional information on appending
site-specific paths to the module search path is available in the
official documentation of the site module.
When binary packages ship identical source code for multiple Python
versions, for instance /usr/lib/python2.6/dist-packages/foo.py and
/usr/lib/python2.5/site-packages/foo.py, these should point to a
common file. Version specific directories for identical source code
are not required for python3 and must not be used for this. A common
location to share, across Python versions, arch-independent files
which would otherwise go to the directory of system public modules is
/usr/share/pyshared. For python3, a special location is not required,
use /usr/lib/python3/dist-packages
1.6 Hooks for updates to installed runtimes
The python binary package has special hooks to allow other packages to
act upon updates to the installed runtimes. This mechanism is required
to handle changes of the default Python runtime in some packages and
to enable the Python packaging helpers. There are three supported hook
types which come in the form of scripts which are invoked from the
maintainer scripts of the Python runtime packages when specific
installations, removals, or upgrades occur.
/usr/share/python/runtime.d/*.rtinstall: these are called when a
runtime is installed or becomes supported. The first argument is
"rtinstall", the second argument is the affected runtime (for example
pythonX.Y) and the third and fourth argument are the old and new
version of this packaged runtime if this runtime was already installed
but unsupported.
/usr/share/python/runtime.d/*.rtremove: these are called when a
runtime is removed or stops being supported. The first argument is
"rtremove", and the second argument is the affected runtime (for
example pythonX.Y).
/usr/share/python/runtime.d/*.rtupdate: these are called when the
default runtime changes. The first argument is either "pre-rtupdate",
called before changing the default runtime, or "rtupdate", called when
changing the default runtime, or "post-rtupdate", called immediately
afterwards. The second argument is the old default runtime (for
example pythonX.Y), and the third argument is the new default runtime
(for example pythonX.Z).

How do I embed a python library in a C++ app?

I've embedded python on a mobile device successfully, but now how do I include a python library such as urllib?
Additionally, how can I include my own python scripts without a PYTHONPATH?
(please note: python is not installed on this system)
The easiest way is to create a .zip file containing all the python code you need and add this to your process's PYTHONPATH environment variable (via setenv()) prior to initializing the embedded Python interpreter. Usage of .pyd libraries can be done similarly by adding them to the same directory as the .zip and including the directory in the PYTHONPATH as well.
Usage of the setenv() call can cause trouble on Windows if you're mixing c-runtime versions. I spent many aggrivating hours learing that setenv() only sets the environment variables for the version of the c-runtime your compiler ships with. So if, for example, Python was built with VC++ 2005 and your compiler is VC++ 2008, you'll need to use an alternative mechanism. Browsing the sources for py2exe and/or PyInstaller may provide you with a better solution (since you're doing essentially the same thing as these tools) but a simple alternative is to "cheat" by using PyRun_SimpleString() to set the module search path from within Python itself.
snprintf(buff, "import sys\nsys.path.append("%s")\n", py_zip_filename)
PyRun_SimpleString(buff)

Categories

Resources