Correct add site-packages folder to Sublime Text 3 sys.path
Asked Answered
D

1

3

1. Summary

I don't understand, how I can make, that global site-packages path will add to Sublime Text 3 sys.path in each Sublime Text 3 start.


2. Reason

I want, that in Sublime Text plugins would be possible use globally installed packages.

See more in Global Python packages in Sublime Text plugin development question.


3. Example

Example part of my plugin:

import os
import sublime_plugin
import sys

from duckduckgo import query  # noqa
from pygoogling.googling import GoogleSearch  # noqa

# Any actions

Where duckduckgo and pygoogling.googling — Python modules from site-packages folder.

Real plugin example.


4. Not helped

4.1. Manually add path to console

I open Sublime Text console → I paste to it:

import sys; sys.path.append('C:\Python36\Lib\site-packages')

Now:

>>> sys.path
['D:\\Sublime Text Build 3143 x64 For Debug', 'D:\\Sublime Text Build 3143 x64 For Debug\\python3.3.zip', 'D:\\Sublime Text Build 3143 x64 For Debug\\Data\\Lib\\python3.3', 'D:\\Sublime Text Build 3143 x64 For Debug\\Data\\Packages', 'C:\\Python36\\Lib\\site-packages']

I restart Sublime Text → I open Sublime Text console:

>>> import sys; sys.path
['D:\\Sublime Text Build 3143 x64 For Debug', 'D:\\Sublime Text Build 3143 x64 For Debug\\python3.3.zip', 'D:\\Sublime Text Build 3143 x64 For Debug\\Data\\Lib\\python3.3', 'D:\\Sublime Text Build 3143 x64 For Debug\\Data\\Packages']

Environment variables, added manually, clean after each restart.

4.2. Using PYTHONPATH

My PYTHONPATH user variable in interpreter:

>>> import sys; sys.path
['', 'C:\\Python36', 'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib', 'C:\\Python36\\lib\\site-packages']

I modify my plugin:

import os
import sublime_plugin
import sys

sys.path.append((os.environ['PYTHONPATH']))

from duckduckgo import query  # noqa
from pygoogling.googling import GoogleSearch  # noqa

# Any actions

Now:

>>> import sys; sys.path
['D:\\Sublime Text Build 3143 x64 For Debug', 'D:\\Sublime Text Build 3143 x64 For Debug\\python3.3.zip', 'D:\\Sublime Text Build 3143 x64 For Debug\\Data\\Lib\\python3.3', 'D:\\Sublime Text Build 3143 x64 For Debug\\Data\\Packages', 'C:\\Python36']

But Sublime Text doesn't accept modules from site-packages:

reloading plugin KristinitaLuckyLink.KristinitaLuckyLink
Traceback (most recent call last):
  File "D:\Sublime Text Build 3143 x64 For Debug\sublime_plugin.py", line 109, in reload_plugin
    m = importlib.import_module(modulename)
  File "./python3.3/importlib/__init__.py", line 90, in import_module
  File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked
  File "D:\Sublime Text Build 3143 x64 For Debug\sublime_plugin.py", line 915, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "D:\Sublime Text Build 3143 x64 For Debug\Data\Packages\KristinitaLuckyLink\KristinitaLuckyLink.py", line 40, in <module>
    from duckduckgo import query  # noqa
ImportError: No module named 'duckduckgo'

4.3. site-packages environment variable

I modify my plugin as in Anthony Perrot answer:

import os
import sublime_plugin
import sys

python_environment_variable = (os.environ['PYTHONPATH'])
sys.path.append(python_environment_variable)

site_packages = next(p for p in python_environment_variable if 'site-packages' in p)
sys.path.append(site_packages)

from duckduckgo import query  # noqa
from pygoogling.googling import GoogleSearch  # noqa

# Any actions

I get StopIteration exception in console:

reloading plugin KristinitaLuckyLink.KristinitaLuckyLink
Traceback (most recent call last):
  File "D:\Sublime Text Build 3143 x64 For Debug\sublime_plugin.py", line 109, in reload_plugin
    m = importlib.import_module(modulename)
  File "./python3.3/importlib/__init__.py", line 90, in import_module
  File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked
  File "D:\Sublime Text Build 3143 x64 For Debug\sublime_plugin.py", line 915, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "D:\Sublime Text Build 3143 x64 For Debug\Data\Packages\KristinitaLuckyLink\KristinitaLuckyLink.py", line 36, in <module>
    site_packages = next(p for p in python_environment_variable if 'site-packages' in p)
StopIteration

5. Worked, but unexpected

5.1. Working example

I add new environment variable to my operating system, for example:

PYTHONPACKAGES=C:\Python36\Lib\site-packages

Where:

And modify my plugin:

import os
import sublime_plugin
import sys

sys.path.append((os.environ['PYTHONPACKAGES']))

from duckduckgo import query  # noqa
from pygoogling.googling import GoogleSearch  # noqa

# Any actions

Plugin will successful works.

5.2. Reason, why unexpected

Each user, who will download my plugin, need add PYTHONPACKAGES environment variable for operating system and, possibly, restart operating system.

It would be nice, if would be possible, that users of plugin don't need add environment variables.

Expected behavior: user install plugin → user can work with plugin without additional actions of setting up.


6. Do not offer

  1. Please, do not offer, that I don't need to use global modules and I need to integrate external modules to plugin folder.
Dx answered 16/1, 2018 at 8:25 Comment(5)
You're worried that every user that uses your packages is going to need to set an environment variable so that Sublime can see your packages when you should be worried that every user that uses your packages has to install Python 3.3 and then install the modules your packages want to use first.Nikolaus
@OdatNurd: thanks for the comment. // Yes, I know, that users needs to install Python and Python modules. But it simply — pip install examplemodule. // every user that uses your packages has to install Python 3.3 — yes, all modules for Sublime Text packages must be compatible with Python 3.3, but globally user can install higher Python version. I use last stable version (3.6.4 at the time). Thanks.Oregano
What I meant was, if the user has to manually install libraries external to Sublime in order for your package to work, why is it to much to also get them to set an environment variable?Nikolaus
@OdatNurd: 1. Adding new environment variable and restarting — additional work for users. If not possible use plugin without it — OK; but if it possible, plugin developer need to make life easier for users. // 2. PYTHONPATH variable have all users, that install Python. site-packages is a part of PYTHONPATH. It would be nice, if would be possible don't add new environment variable, but use already exist PYTHONPATH. Thanks.Oregano
My answer in the question you linked to tells you how to add something to the path at startup (well, plugin load time, but that's about as close as you can get from within Sublime). The question you should be asking is less "how do I make it add to the path at startup" and more "how do I know what path I should be adding at startup", I think. If you can figure that out, the other part is easier.Nikolaus
C
1

You can also do this using the following:

import site

# if outside of a sublime text plugin class
all_views = sublime.active_window().views()
# or if inside use the 'view' variable, skip to line 9 and change 
# all_views[0].settings to view.settings

if len(all_views) > 0:
    external_python_path = all_views[0].settings().get("external_python_path")

    sp = site.getsitepackages(external_python_path)
    sp = [x for x in sp if "site-packages" in x.lower()]
    sys.path.append(sp)

then in your Preferences.sublime-settings file, you add a key:value like

{
    "somekey": "somevalue",
    ...,
    "external_python_path": "path_to_python folder excluding the python.exe"
}
Coolish answered 17/1, 2019 at 7:31 Comment(1)
Tushortz, I'm sorry, I need to create Sublime Text plugin with your Python code or I need your code to use something else? Thanks.Oregano

© 2022 - 2024 — McMap. All rights reserved.