Sublime Forum

Configuring a build system for python3 (run files as modules)

#1

Hello, I’m struggling with a regex and I need it to be dynamic , but I can’t get it in one shot,. I read [this] (http://docs.sublimetext.info/en/sublime-text-3/extensibility/snippets.html#substitutions) and here my “python3.sublime-build” file is it possible nested substitutions?.

{
“cmd”: ["/usr/bin/python3", “-u”, “-m”, “${file///}”]
, “working_dir”: “/home/bar/spam/regex/TFG/”
, “selector”: “source.python”
, “file_regex”: “file “(…*?)”, line ([0-9]+)”
}

now it does nothing, but I tried it all.

Basically I have, this string “/foo/bar/spam/regex/TFG/pacman/search/file.py” and I need this from TFG/ onward “pacman.search.file” so when I run the current file using that build (ctrl+b) actually it’ll be running something like “python3 -u -m pacman.search.file” instead of “python3 -u -m /foo/bar/spam/regex/TFG/pacman/search/file.py” keeping in mind the work directory is set in “.sublime-build”.

I really need help, regards

0 Likes

#2

I have a similar wish, to be able to add to the line number returned from the regex, but unfortunately this is currently not possible.

0 Likes

#3

 
Try writing a separate build script instead of executing python directly.   Doing so would allow you to manipulate the passed arguments as necessary.

I posted a thread that demonstrates my personal build system for Windows.  Maybe you can get some context from checking it out & use it as a reference to write one of your own.

0 Likes

#4

Unfortunately your task would require building a path relative to a certain directory, the project folder, which can not be done dynamically with just build systems. You’d need to either hard-code paths in the build system (as you seem to be doing already anyway) or write a Python plugin.

Going down the first option, which is more simple, you’d do something along the lines of this (untested):

"cmd": ["/usr/bin/python3", "-u", "-m", "${file/\\/home\\/bar\\/spam\\/regex\\/TFG\\/|(\\/)/(?1:.:)/}"]
0 Likes

#5

Thank you guys. I opted for the fico’s solution, I wrote a simple python script which is called from the build system and it’s there where the actual file that I want to run from ST is executed by using the subprocess module. Probably is not the best sol but it’s not gonna be production code :stuck_out_tongue:

1 Like

#6

2 Likes

#7

In case anybody else comes across this, here’s a bash script and accompanying sublime-build I used to make this happen. It relies on the $folder and $file variables populated by the Sublime Build.

My sublime-build is this:

{
 	"selector": "source.python",
    "working_dir": "$folder",
 	"shell_cmd": "bash $folder/run-as-module.sh $folder $file", 
    "file_regex": "^\\s*File \"(...*?)\", line ([0-9]*)"
}

And the bash script run-as-module.sh is this

#!/bin/bash

# Configure sublime build system so it always runs python from highest level directory
# So relative imports work
# E.g. doesn't run "python3 -m myfile" but rather "python3 -m module.myfile"

# Check if correct number of arguments are provided
if [ "$#" -ne 2 ]; then
echo "Usage: $0 folder_name file_name" >&2
exit 1
fi

# Extract folder name and file name
folder_name="$1"                                # e.g. /Users/.../Code/top
file_name="$2"                                  # e.g. /Users/.../Code/top/module/myfile.py

# Remove folder name from file name
module_name="${file_name#$folder_name/}"        # e.g. module/myfile.py

# Replace "/" with "."
module_name="${module_name//\//.}"              # e.g. module.myfile.py

# Replace ".py" with nothing
module_name="${module_name//.py/}"              # e.g. module.myfile

# Run Python module
python3 -m "$module_name" # The -m flag ensures relative imports work in packages
0 Likes