I am trying to set up a python 3 build path for sublime text 3 on a windows 10 pc. The system says that it cannot find the specified file, but I have already added the path and set the build system for python3. The error message I get when I try to build is below..
[WinError 2] The system cannot find the file specified
[cmd: ['python3', '-i', '-u', 'C:\\Users\\strinkjr\\Desktop\\Python Stuff\\errorSearch.py']]
[dir: C:\Users\strinkjr\Desktop\Python Stuff]
[path: C:\Users\strinkjr\Desktop\Python Stuff\]
[Finished]
My build environment file is as follows:
{
"cmd": ["python3", "-i", "-u", "$file"],
"file_regex": "^[ ]File \"C:/Users/strinkjr/AppData/Local/Programs/Python/Python36/python.exe\", line ([0-9]*)",
"selector": "source.python"
}
I am unsure if I set up the path incorrectly or if I set up the build environment incorrectly. (Maybe both)
There are a couple of overall problems you're having that are standing in your way here.
The first is that you didn't set the PATH correctly. The build output shows you the PATH as it's currently defined as far as the command execution is concerned:
[path: C:\Users\strinkjr\Desktop\Python Stuff\]
The PATH is the list of locations where windows will look for the program that you're trying to execute, so unless there is a python3.exe in this directory you've accidentally set the PATH to the location of the files that you're running and not the interpreter that's used to run them.
Secondly you're passing -i to the Python interpreter to get it to drop into interactive mode once it's done executing the script. Sublime doesn't let you interact with programs that you execute from within a sublime-build, so if you do this once your program finishes executing and goes into interactive mode, it's going to be effectively hung waiting for you to provide it input that you can't provide.
Your build system also contains this file_regex entry:
"file_regex": "^[ ]File \"C:/Users/strinkjr/AppData/Local/Programs/Python/Python36/python.exe\", line ([0-9]*)",
In a sublime-build file, the file_regex is used to be able to detect what lines in the program's output are errors so that Sublime can allow you to navigate between errors or flag them with inline errors if you have that option turned on.
Although this won't stop your programs from running, it will stop Sublime from being able to recognize errors because the name of the file is never going to match.
I would try a sublime-build file something like the following and see if that works better for you:
{
"shell_cmd": "python3 -u \"$file\"",
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
"env": {
"PYTHONIOENCODING": "utf-8",
"PATH": "$PATH;C:/Users/strinkjr/AppData/Local/Programs/Python/Python36/"
},
}
This removes the -i argument to stop the interpreter from going interactive in order to stop any problems and uses shell_cmd instead of cmd to provide the command, which changes the format slightly.
The file_regex here is one that will match regular python errors, which is similar to the one you already provided but without the reference to the Python executable.
The big addition here is a couple of environment variables. The first one ensures that Python knows that it should use utf-8 to generate output, since that's what the Sublime console is expecting it to use. That stops you from getting potential errors if you try to display non-ascii output.
This also applies a new PATH that includes the existing path and also adds to it the path that looks like it might be where your Python is installed based on the files you were already using.
That part may need adjustment if the location is not correct; alternatively you can remove the PATH portion of the sublime-build and modify your PATH environment variable as appropriate instead. Note that you may need to restart Sublime if you do that in order for it to see the change.
Related
When you run Sublime Build and it finishes, there is a message [Finished ] (in the picture). I would like to add default message when every Build starts to be like "[Started]":
Also it would be nice to add local time when Build System started, e.g. [Started 22:20:23]
The are (at least) three ways to do this. The first way is to add the functionality to the beginning of your code, so it prints out the information you want. The disadvantage of this method is that the message is printed only when the code begins to run, not at the beginning of the build. Depending on the language you're using, whether it's compiled or interpreted, and the size of your codebase, this could be a significant lag.
The second method is to run your build through a shell file which executes using bash. On Windows, this requires that you have bash installed - Git Bash and Cygwin are two common ways of obtaining it. The following script accepts an arbitrary number of arguments, which it runs after printing "Started" and the date.
#!/bin/bash
echo "[Started at `date`]"
# check to see if we have at least 1 arg
if [ $1 ]
then
# replace this process w/ arg(s) so `exec.py` (the Sublime
# build system) gets the proper return value
exec "${#}"
fi
Save this file as build.sh somewhere in your PATH.
Now, take a look at the .sublime-build file for the build system you're using, specifically the "shell_cmd" or "cmd" line. If it's a "shell_cmd", all you'll need to do is copy and paste it (without the enclosing double quotes) into the build system below. If it's a "cmd", convert the array/list following "cmd": to a single string. So, for example, if you're using the default Python build system on Windows, "cmd": ["py", "-u", "$file"] would become py -u $file. Essentially, you're converting the array to what you would type at the command prompt, keeping Sublime-internal variables beginning with $ (like $file) intact.
Next, select Tools → Build System → New Build System…. Erase its contents and paste in the following template:
{
"shell_cmd": "bash -c \"build.sh new_cmd_goes_here\"",
"working_dir": "$file_path",
// "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
// "selector": "source.python",
// "env": {"PYTHONIOENCODING": "utf-8"}
}
replacing new_cmd_goes_here with the command string you just created in the step above. So, for our Python example, that line would become:
"shell_cmd": "bash -c \"build.sh py -u $file_name\"",
You can uncomment the commented-out lines in the build system template if you wish.
When you're done editing the build system, simply hit CtrlS to save, naming it something like Python (start message).sublime-build, for example. You don't need to change the directory the file is saved in, as Sublime will automatically put it in your Packages/User directory.
The third option is to modify Packages/Default/exec.py to fit your needs. This requires knowledge of Python and Sublime's internals. You can find the basics of how build systems work and how to extend them here.
Briefly, you would save Packages/Default/exec.py as Packages/User/exec_with_dt.py, setting the read_only flag to False if necessary. Next, change the name of the ExecCommand class to ExecWithDtCommand. Then, just after self.proc is defined as an AsyncProcess, add a line calling either self.append_string() (ST3) or self.write() (ST4) writing your desired string to the output. In ST4, I used:
from datetime import datetime as dt
self.write("[Started " + dt.now().strftime("%Y-%m-%d %H:%M:%S") + "]\n")
I haven't tested this in ST3, but the following should work there:
from datetime import datetime as dt
self.append_string(None, "[Started " + dt.now().strftime("%Y-%m-%d %H:%M:%S") + "]\n")
Save the file, then create a new build system with the following contents:
{
"target": "exec_with_dt",
"cmd": ["py", "-u", "$file"],
}
I don't recommend this approach unless you really know what you are doing, and the shell script method isn't sufficient for your needs. Other edits may need to be made to exec_with_dt.py to ensure complete parallel functionality with the original exec.py, so look through it carefully. For example, you may want to modify ExecEventListener to ExecWithDtEventListener and change its code to run the exec_with_dt command, just to keep everything in-house.
How can I create a build system in Sublime Text 3 where "cmd" is replaced with a shebang if it exists?
More specifically, is there a way to alter the Python build system to use the version of Python specified in the shebang, and use a default if no shebang is present?
Sublime build systems have an option named target which specifies a WindowCommand that is to be invoked to perform the build. By default this is the internal exec command. You can create your own command that would examine the file for a shebang and use that interpreter or some default otherwise.
For example (caveat: I'm not super proficient in Python so this is probably quite ugly):
import sublime, sublime_plugin
class ShebangerCommand(sublime_plugin.WindowCommand):
def parseShebang (self, filename):
with open(filename, 'r') as handle:
shebang = handle.readline ().strip ().split (' ', 1)[0]
if shebang.startswith ("#!"):
return shebang[2:]
return None
def createExecDict(self, sourceDict):
current_file = self.window.active_view ().file_name()
args = dict (sourceDict)
interpreter = args.pop ("interpreter_default", "python")
exec_args = args.pop ("interpreter_args", ["-u"])
shebang = self.parseShebang (current_file)
args["shell_cmd"] = "{} {} \"{}\"".format (shebang or interpreter,
" ".join (exec_args),
current_file)
return args
def run(self, **kwargs):
self.window.run_command ("exec", self.createExecDict (kwargs))
You would save this in Packages/User as a python file (e.g. shebanger.py).
This creates a new command named shebanger that collects the arguments it's been given, examines the file in the currently active view of the window the build is triggered in to see if the first line is a shebang, and then synthesizes the arguments needed for the exec command and runs it.
Since the default python build system assumes it is building the current file and passing -u as an argument, that's what this command replicates as well. Note however that this code is not 100% correct because any arguments in the shebang line will be ignored, but you get the general idea.
In use, you would modify the default Python.sublime-build file to look like this:
{
// WindowCommand to execute for this build
"target": "shebanger",
// Use this when there is no shebang
"interpreter_default": "python",
// Args to pass to the interpreter
"interpreter_args": ["-u"],
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
"env": {"PYTHONIOENCODING": "utf-8"},
"variants":
[
{
"name": "Syntax Check",
"interpreter_args": ["-m py_compile"],
}
]
}
Notice that in the variant we override what the interpreter arguments are; you could also override the default interpreter there as well if desired.
If think the only way to do this using a standard .sublime-build file is to pass your file to another script which then parses the shebang and passes it on to the correct Python version.
Alternatively, you could specify build variants, but then you will have to choose the desired build variant manually.
My python.sublime-build
{
"cmd": ["py", "-u", "$file"],
"file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
"selector": "source.python",
"shell":true
}
In windows I used py launcher to detect the versions according to the shebang
I am using this command to source get.tcl file and giving options 'verbose' and 'instant':
source -verbose -instant get.tcl
the above command worked for me in tcl 8.4 but showing this error in tcl 8.5
source (script wrong # args: should be "source_orig ?-encoding name?
fileName"
if I write only
source get.tcl
It get passed in tcl 8.5
Is there any change related to this in tcl 8.5?
The source command only accepts one option (since 8.5), -encoding, which is used to specify what encoding the file being read is in (instead of the default guess of encoding as returned by encoding system). All it does is read the file into memory and (internally-equivalent-to-) eval the contents.
You can write to any variable you want prior to doing the source, including global variables like argv. With that (plus appropriate use of uplevel and catch, as required, and maybe also interp create) you can simulate running the script as a subprocess. But it's probably easier to not have the file expect to be handling arguments like that, and instead for it to define a command that you call immediately after the sourcing.
You can pass arguments to your sourced file by doing the following:
set ::argv [list -verbose -instant]
source get.tcl
I recommend using:
set ::argv [list -- -verbose -instant]
The -- will stop tclsh from processing any arguments after the --.
Sometimes tclsh will recognize an argument that is meant for your
program and process it. Your programs will need to know about
the -- and handle it appropriately.
I can't get Python 3 to print out anything while running a script in Sublime Text. I can get it to print out after the script has finished, but I need it to print as it goes.
Here's some example code
import time
for x in range(10):
print("Test")
time.sleep(1)
Using Python 3 as the build system, I get nothing for 10 seconds, and then 10 "Tests" printed all at once.
If I run the same script using the Python 2 build system, I get 1 "Test" printed out each second, which is what I want.
Similarly if I run the script using "python3 script.py" in the terminal I get 1 "Test" printed out each second.
Can anyone tell me how to make the build system in Sublime Text 3 print out Python 3 while it runs?
You have to open your Python 3 build system configuration file, and ensure that the -u option is supplied to the command line to be executed.
For example:
# ~/.config/sublime-text-3/Packages/User/Python3.sublime-build
{
"cmd": ["/usr/bin/python3.5", "-u", "$file"],
"selector": "source.python",
"file_regex": "file \"(...*?)\", line ([0-9]+)"
}
Quoting the documentation:
-u
Force the binary layer of the stdout and stderr streams (which is
available as their buffer attribute) to be unbuffered. The text I/O
layer will still be line-buffered if writing to the console, or
block-buffered if redirected to a non-interactive file.
With this option, the ouptut of your Python script will be correctly displayed into Sublime Text while running.
I use a program which create me postscript file before using ps2pdf to make it a readable pdf, i've made a program which add some string to overwrite the company new logo. (The first program can't import image file itself).
I add the string before the before-last line of the file (" showpage").
While running my program to add the logo there is no error.
With the option -dNOSAFER everything is fine, but by default it's set to -dSAFER, and an invalidfileaccess error pop, the files are 6 jpg images alone in their directory.
I don't want to make it run with the -dNOSAFER option on. As it will fully open the file system.
In the documentation I've seen that there is a "permitted path" setting, but i can't find nowhere to set this up. Is it just a command line option to set in the command launching the program ? Or is there a config file for GhostScript / ps2pdf where i can put the path to this directory as permitted path.
in this documentation :
http://www.ghostscript.com/doc/current/Use.htm
I only find
-dTTYPAUSE
Causes Ghostscript to read a character from /dev/tty, rather than
standard input, at the end of each page. This may be useful if input
is coming from a pipe. Note that -dTTYPAUSE overrides -dNOPAUSE. Also
note that -dTTYPAUSE requires opening the terminal device directly,
and may cause problems in combination with -dSAFER. Permission errors
can be avoided by adding the device to the permitted reading list
before invoking safer mode
gs -dTTYPAUSE -dDELAYSAFER -c '<< /PermitFileReading [ (/dev/tty)] >> setuserparams .locksafe' -dSAFER
The quote is just for the context but is this a way to put the permitted path ?
As gs automatically launch with the full system as readOnly there will be no difference ? There is no other find result for PermitFile in this page.
Try adding the required path to the search path with -I (Include) See Use.htm, section 8 How Ghostscript finds files. This should only be a problem if you are using 'run' or similar to read files from another location.
The section on TTYPAUSE is not relevant.