Integration of a script writen in Python
-
@Ekopalypse said in Integration of a script writen in Python:
A word of warning if you use the default startup.py file.
The default startup.py will be overwritten when PS is updated.
Therefore, create your own startup.py file by simply creating a new script and naming it startup.py.
If you use the version installed by PluginAdmin, it is unlikely that this version will be updated, but the PS3 version will be updated from time to time.Interesting. I don’t think I’ve ever known this.
So there’s a
startup.py
in...\plugins\PythonScript\scripts\
folder.
If you modify it, it will work but this one is the one in danger of being overwritten on a PS update.If you move the file to
...\plugins\Config\PythonScript\scripts\
folder then it still works just fine but is out of danger from being clobbered by a PS update.Is that accurate information?
-
@Alan-Kilborn said in Integration of a script writen in Python:
Is that accurate information?
As far as I understand it.
The first, in
...\plugins\PythonScript\scripts\
folder, is the “machine scripts” instance; the second, in...\plugins\Config\PythonScript\scripts\
, is the “user scripts” version (using the nomenclature from the Python Script > Configuration… dialog).Moreover, if you have both startup files, both will be listed in your Plugins > Python Script > Scripts menu, with the second (the “user scripts” version from the Config hierarchy) will have
(User)
appended to the displayed name:
I just ran an experiment with the two: I put in a print statement (well,
console.write()
) in bothstartup.py
scripts; the machine-scripts instance runs first, followed by the user-scripts instance. (That’s what I thought happened, but wanted to make sure before saying it here, because the...PythonScript/doc/usage.html#startup
section is not explicit about it using both, or what order they run in.) -
Alan, yes, it is as Peter explained.
-
Looking back on it, I probably knew most of that. :-)
But I did not know that the non-userstartup.py
can get clobbered.So I’d say the best course of action for a normal user is to ignore the non-user (aka machine scripts) one, and, if you need to run stuff on startup, create your own
startup.py
(create it just like any other new script you’d make) and put your stuff in it.The temptation is to just quickly throw stuff into the file that already exists – don’t do it.
-
@Alan-Kilborn - absolutely
-
Thanks for your additions.
I already used the
startup (user)
script.Kind Regards,
Thomas -
I opened the issue 205 for the difference in “preloaded” modules.
-
-
@tho-gru ,
To use different words than @Alan-Kilborn and @Ekopalypse have already used to try to explain this to you:
As was explained to you above by @Ekopalypse (in case @Alan-Kilborn’s link doesn’t work well – links to individual posts in the NodeBB-based forum don’t highlight the post, and sometimes don’t scroll to the part of the post you expect them to – you can look in this topic for where @Ekopalypse said, “because it is then defined in the main namespace”) before you created the issue 205, when you run a script from the PythonScript Scripts menu, it is in the
__main__
namespace, so if yourstartup.py
has already imported those default symbols, then the names are already defined in that__main__
namespace, and so are available to your script. However, when you have a line instartup.py
that imports your script (theimport TgrUrlAltClick
), Python (not the PythonScript plugin) puts that whole file in its own namespace (TgrUrlAltClick
, in your example). Thus, in the context of that imported script, theTgrUrlAltClick
namespace has never imported the symbols from the Npp module, and that is why the Npp-defined objectsnotepad
,console
, andeditor
are not available to functions in yourimport
ed script.The PythonScript plugin cannot and will not redefine the Python language
import
mechanism to inject the__main__
namespace symbols into whatever scripts you happen toimport
viastartup.py
.The PythonScript plugin cannot and will not do any magic in
startup.py
that will be able to recognize when animport
instartup.py
is really trying to auto-execute a user-defined script rather than importing a standard Python library, so cannot and will not try to magically inject the__main__
namespace symbols into the scripts you happen toimport
viastartup.py
.You can and should and are expected to import the symbols that you need from the Npp module into any script that you desire to
import
fromstartup.py
or from any other script, because that is the only way to guarantee that any script you write will have access to those symbols whether the script is run from the PythonScript Scripts menu or by beingimport
ed as a module from another script. Adding the linefrom Npp import *
(or a reduced version if you don’t need all the Npp symbols) into all your scripts is not an onerous task on your part, and importing modules and symbols is an expected aspect of any Python development, not just PythonScript development.(A copy of this has also been posted in your issue)
-
@PeterJones I fully understand that I need to import symbols from other modules by typing
import ...
.Unfortunately (now I understand why) I did not get an error message while executing the script via the menu. My complain is not the need of importing modules I am using in my script. My complain is that I want to get same error messages independent how I can start a python script.
I currently see two possible solutions to achieve this:
- hide (unload or what ever possible) the console module for scripts started via the menu
- “preload” the console module to be available for all script started via the startup.py (user or system)
Of course the should be done for all “preloaded” modules available in scripts started via the menu.
This should simply remind beginners to
import
the modules needed.Kind Regards
Thomas -
@tho-gru said in Integration of a script writen in Python:
@PeterJones I fully understand that I need to import symbols from other modules by typing
import ...
.Not fully, because your option 2 below seemed to indicate you still think it’s possible to pre-load it.
I currently see two possible solutions to achieve this:
- hide (unload or what ever possible) the console module for scripts started via the menu
Then change the
from Npp import *
from the machine and userstartup.py
toimport Npp
yourself. That way, the errors will come from the beginning for you, without influencing other people who do not want to have to do the imports when using the PythonScript console in immediate mode. (If you do this, calls to the standard objects inside thestartup.py
scripts will have to be prepended withNpp
.)- “preload” the console module to be available for all script started via the startup.py (user or system)
Of course the should be done for all “preloaded” modules available in scripts started via the menu.
As already explained in detail above, but I’ll try to phrase it differently, because you have not understood, despite saying that you understand: The
startup.py
currently preload the Npp instance variables into the__main__
namespace, and thus for every script started from the menu, those constants are pre-loaded. But that cannot affect scripts that youimport
into yourstartup.py
script, because that’s not the way Pythonimport
works – when you import a module in a given, it imports into the current namespace seen by that file;startup.py
are in the__main__
namespace, so they import symbols into the__main__
namespace; scripts run from the menu are in the__main__
namespace, so they import symbols into the__main__
namespace; but a script likeTgrUrlAltClick.py
that is imported into some other script (like usingimport TgrUrlAltClick
instarup.py
to import a script rather than a standard module) is in its own namespace, so none of the functions defined insideTgrUrlAltClick.py
will see the__main__
namespace symbols because functions insideTgrUrlAltClick.py
are in theTgrUrlAltClick
namespace in this condition.What you are asking in point#2 is the equivalent of saying that when you have the following situation, it should work instead of throwing a NameError exception.
C:\usr\local\apps\python-3.9.6-embed-amd64>type mainFile.py #!python # encoding=utf-8 from sys import path from MyOtherScript import myFunction myFunction() C:\usr\local\apps\python-3.9.6-embed-amd64>type MyOtherScript.py #!python # encoding=utf-8 print("Hello from namespace '{}'!\n".format(globals()['__name__'])) def myFunction(): print(path) C:\usr\local\apps\python-3.9.6-embed-amd64>python mainFile.py Hello from namespace 'MyOtherScript'! Traceback (most recent call last): File "C:\usr\local\apps\python-3.9.6-embed-amd64\mainFile.py", line 6, in <module> myFunction() File "C:\usr\local\apps\python-3.9.6-embed-amd64\MyOtherScript.py", line 7, in myFunction print(path) NameError: name 'path' is not defined
This should simply remind beginners to
import
the modules needed.Beginners don’t import their scripts into
startup.py
; beginners run their scripts manually from the menu. People who want to do more advanced actions, like automatically running their script fromstartup.py
by importing the script via a command instartup.py
need to learn about things like namespaces and importing, and need to actually understand those concepts … or at least be willing to take the advice to “alwaysfrom Npp import *
in every script if you’re going to do anything but run your script from the menu”. -
@PeterJones said in Integration of a script writen in Python:
People who want to do more advanced actions,
Also, people who want to do more advanced actions read the manual that’s included with PythonScript plugin, which says quite explicitly in the Npp Module section of the Introduction:
Honestly, beginners, not just people moving on to advanced topics, should have also at least read the whole introduction.
The manual was quite explicit: if you want to write a module (a new file) that is called from someplace else (which is exactly what you do when you import your script into
startup.py
), then you need to include thefrom Npp import *
inside your module.We’ve told you. The manual has told you. Good luck.