Sublime Forum

[SOLVED] Python's subprocess.call error only from plugin

#1

Hi, I’m developing a very simple plugin, the idea is to format current file when on_post_save triggers, it uses Standard JS for this, and I’m running it with subprocess.call, but is not working, I’m getting a 127 error. The weird thing is that exactly same command run from python interpreter works perfectly fine, any ideas? Is there some kind of sandbox for plugins? Thanks!

0 Likes

#2

What is the command?

0 Likes

#3

I’m running standard (http://standardjs.com/), tried using the globally installed standard, and I get FileNotFoundError: [Errno 2] No such file or directory: 'standard', and also tried using the absolute path to the standard binary, here’s the code:

import sublime_plugin
import re
import subprocess
import os.path

class SublimeOnSaveBuild(sublime_plugin.EventListener):
    def on_post_save(self, view):

        if not re.search("\\.js$", view.file_name()):
            return

        print(":: Format with Standard JS ::")

        path = view.file_name()
        parent = False

        while not parent:
            path = path.rsplit("/", 1)[0]
            if os.path.isfile(path + "/package.json"):
                parent = True
        
        standard = path + "/node_modules/.bin/standard" 
        if os.path.isfile(standard):
            #print(subprocess.call(["standard", "--fix", view.file_name()]))
            print(subprocess.call([standard, "--fix", view.file_name()]))
0 Likes

#4

Are you on OS X?

From a first look, the code looks okay, although you could be using the os.path functions instead of directly operating on strings. What does running the code output?

0 Likes

#5

Yeap, it’s macOS, the output is 127, error code for file not found according to google, how can I use os.path functions to improv the code?
Are sublime plugins running in an isolated environment or something similar? I can’t find out why on terminal works…

0 Likes

#6

Install the FixMacPath package (or similar). The reason is that applications launched from the doc don’t inherit the shell environment.

This is going to be fixed in a future build.

1 Like

#7

That worked perfectly, thank you very much!

0 Likes

#8

Hi!

This is not about your original problem, this is just a few tips:

Basically, you want to check the extension of the file:

os.path.splitext('myfile.old.py') == ('myfile.old', '.py')
# So just do
if os.path.splitext(v.file_name())[1] != '.js':
     return

With this, you’re not loading regex just for this.

Have a look at os.path, there’s plenty of good suprises! see on devdocs

And, you’re calling view.file_name() few times although you’ve saved it in path, it’s not really optimised. :wink:

Mathieu

0 Likes

#9

Thanks, that looks better, path is being mutated inside the while loop, so the only place where I can replace the v.file_name() is in the if, but for that I have to declare and assign path before knowing if it’s a js file.

0 Likes