.pyc file closes immediately - python

I am using this code to convert .py file into .pyc
import py_compile
import os
import glob
path = ''
for infile in glob.glob( os.path.join(path, '*.py') ):
print(f"current file is: {infile}")
strDestination = 'compiled/' + infile + 'c'
py_compile.compile(infile,strDestination)
I converted 6 similar scripts, that uses:
pandas, calendar, datetime, gc, numpy ,multiprocessing modules. However, when I try to execute .pyc files, 3 one them work fine and 3 of them closes immediately.
I try to add an input() at the start and the end of the code, but it also closes immediately.
If I execute the same script .py, it works normally.
When the conversion occurs, is it necessary to avoid some specific library ?
#### UPDATE
I noticed if I change the name of the .pyc file to the same name of the one that worked, it works. However, it needs to be on the directory folder. Why ?

The answer: .pyc File name cannot have special characters.
I hope this help someone.

Related

Call variables from .py script into Batch

I have a series of .py files that I am using a .bat for to automate the whole process. Within some of the .py files I have called variables from another .py file. I did this to allow myself to only change one .py when running new processes. I have the .bat set up to run normally with the .py files, but I do not understand how to incorporate the variables.py file.
Example:
Python1.py
import os
import somefolder.variables as variables
path = 'C:/pictures/'
file = variables.file
for img in os.listdir(path + variables.file):
print(img)
Variables.py
file = item1.img
Batch.bat
call "C:/Users/name/anaconda3/Scripts/activate.bat" "C:/Users/name/anaconda3/envs/environment"
call "C:/Users/name/anaconda3/envs/environment/python.exe" "D:/Scripts/python1.py"
...
After running something similar to this. I received the error: No module named 'somefolder'. I've read a few other posts about using the echo command or using set, but it seems as that is setting a variable within the batch and not calling it from another .py file. I am farily new to batch files, so any help would be appreciated.
As #Rashid 'Lee' Ibrahim mentioned in the comments above, it would be best to look into using __intit__.py. Though for the sake of getting the code to run, I set where the module/.py file was located as a system path.
Python1.py Original
import os
import somefolder.variables as variables
path = 'C:/pictures/'
file = variables.file
for img in os.listdir(path + variables.file):
print(img)
Python1.py Edited
import os
sys.path.append('D:/Scripts/')
import variables
path = 'C:/pictures/'
file = variables.file
for img in os.listdir(path + variables.file):
print(img)
Read file contents into a variable:
for /f "delims=" %%x in (version.txt) do set Build=%%x
or
set /p Build=<version.txt
Both will act the same with only a single line in the file, for more lines the for variant will put the last line into the variable, while set /p will use the first.
Using the variable – just like any other environment variable – it is one, after all:
%Build%
So to check for existence:
if exist \\fileserver\myapp\releasedocs\%Build%.doc ...
Although it may well be that no UNC paths are allowed there. Can't test this right now but keep this in mind.

Regarding file io in Python

I mistakenly, typed the following code:
f = open('\TestFiles\'sample.txt', 'w')
f.write('I just wrote this line')
f.close()
I ran this code and even though I have mistakenly typed the above code, it is however a valid code because the second backslash ignores the single-quote and what I should get, according to my knowledge is a .txt file named "\TestFiles'sample" in my project folder. However when I navigated to the project folder, I could not find a file there.
However, if I do the same thing with a different filename for example. Like,
f = open('sample1.txt', 'w')
f.write('test')
f.close()
I find the 'sample.txt' file created in my folder. Is there a reason for the file to not being created even though the first code was valid according to my knowledge?
Also is there a way to mention a file relative to my project folder rather than mentioning the absolute path to a file? (For example I want to create a file called 'sample.txt' in a folder called 'TestFiles' inside my project folder. So without mentioning the absolute path to TestFiles folder, is there a way to mention the path to TestFiles folder relative to the project folder in Python when opening files?)
I am a beginner in Python and I hope someone could help me.
Thank you.
What you're looking for are relative paths, long story short, if you want to create a file called 'sample.txt' in a folder 'TestFiles' inside your project folder, you can do:
import os
f = open(os.path.join('TestFiles', 'sample1.txt'), 'w')
f.write('test')
f.close()
Or using the more recent pathlib module:
from pathlib import Path
f = open(Path('TestFiles', 'sample1.txt'), 'w')
f.write('test')
f.close()
But you need to keep in mind that it depends on where you started your Python interpreter (which is probably why you're not able to find "\TestFiles'sample" in your project folder, it's created elsewhere), to make sure everything works fine, you can do something like this instead:
from pathlib import Path
sample_path = Path(Path(__file__).parent, 'TestFiles', 'sample1.txt')
with open(sample_path, "w") as f:
f.write('test')
By using a [context manager]{https://book.pythontips.com/en/latest/context_managers.html} you can avoid using f.close()
When you create a file you can specify either an absolute filename or a relative filename.
If you start the file path with '\' (on Win) or '/' it will be an absolute path. So in your first case you specified an absolute path, which is in fact:
from pathlib import Path
Path('\Testfile\'sample.txt').absolute()
WindowsPath("C:/Testfile'sample.txt")
Whenever you run some code in python, the relative paths that will be generate will be composed by your current folder, which is the folder from which you started the python interpreter, which you can check with:
import os
os.getcwd()
and the relative path that you added afterwards, so if you specify:
Path('Testfiles\sample.txt').absolute()
WindowsPath('C:/Users/user/Testfiles/sample.txt')
In general I suggest you use pathlib to handle paths. That makes it safer and cross platform. For example let's say that your scrip is under:
project
src
script.py
testfiles
and you want to store/read a file in project/testfiles. What you can do is get the path for script.py with __file__ and build the path to project/testfiles
from pathlib import Path
src_path = Path(__file__)
testfiles_path = src_path.parent / 'testfiles'
sample_fname = testfiles_path / 'sample.txt'
with sample_fname.open('w') as f:
f.write('yo')
As I am running the first code example in vscode, I'm getting a warning
Anomalous backslash in string: '\T'. String constant might be missing an r prefix.
And when I am running the file, it is also creating a file with the name \TestFiles'sample.txt. And it is being created in the same directory where the .py file is.
now, if your working tree is like this:
project_folder
-testfiles
-sample.txt
-something.py
then you can just say: open("testfiles//hello.txt")
I hope you find it helpful.

Python import module load_source

I have question on the load_source.
when my 2 .py files are in the same directory /home/pi they work fine.
main.py
#!/usr/bin/python
import buttonlog
buttonlog.py
import datetime
i = datetime.datetime.now()
#OPEN FILE & APPEND
f=open('buttonlog.txt','a')
#WRITE DATE THEN NEW LINE WITH THE '\N'
f.write(i.isoformat() + '\n')
When I run python main.py it writes an entry like I'd expect.
However I'd like to store main.py in another directory so I tried this, it is stored in the /home/pi/test
#!/usr/bin/python
import imp
imp.load_source('buttonlog', '/home/pi/buttonlog.py')
When I run python /home/pi/test/main.py I do not get any errors nor does it write an entry into my file. What am I doing wrong?
The secret is the use of the open command.
As the documentation says about the first argument,
file is a path-like object giving the pathname (absolute or relative to the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped.
By passing just "buttonlog.txt", this is not an absolute pathname, so it's relative to the current working directory.
The simplest way to fix this is to use a full path. If you always want it writing in to /home/pi, you just need:
f=open('/home/pi/buttonlog.txt','a')
There are other alternatives, though I think this is the cleanest. You could also change your current working directory prior to issuing the open command for the same results. Simply put this code above the open line:
import os
os.chdir("/home/pi")

Python creates locked files on Ubuntu

I just ran into a problem, which is probably easy to fix - well, for you guys.
I try to create a directory, change to it, create a file in that directory and appened to that file. Everything works fine - except it marks the directory/file as locked and that isn't very convenient for me.
I am running my script as root, because I need to. When I run it normally that problem doesn't occur. I am on Ubuntu and down below is some example code plus a picture of the permissions of the given file, thanks!
import os
os.makedirs("foo", exist_ok = True)
os.chdir("foo")
with open("oof", "a") as f:
f.write("something" + "\n")
As you said you run the script as root so other users can not access this file.
You can change directory permissions:
from subprocess import call
call(['chmod', 'mode', 'path'])

Force python to ignore pyc files when dynamically loading modules from filepaths

I need to import python modules by filepath (e.g., "/some/path/to/module.py") known only at runtime and ignore any .pyc files should they exist.
This previous question suggests the use of imp.load_module as a solution but this approach also appears to use a .pyc version if it exists.
importme.py
SOME_SETTING = 4
main.py:
import imp
if __name__ == '__main__':
name = 'importme'
openfile, pathname, description = imp.find_module(name)
module = imp.load_module(name, openfile, pathname, description)
openfile.close()
print module
Executing twice, the .pyc file is used after first invocation:
$ python main.py
<module 'importme' from '/Users/dbryant/temp/pyc/importme.py'>
$ python main.py
<module 'importme' from '/Users/dbryant/temp/pyc/importme.pyc'>
Unfortunately, imp.load_source has the same behavior (from the docs):
Note that if a properly matching byte-compiled file (with suffix .pyc
or .pyo) exists, it will be used instead of parsing the given source
file.
Making every script-containing directory read-only is the only solution that I know of (prevents generation of .pyc files in the first place) but I would rather avoid it if possible.
(note: using python 2.7)
load_source does the right thing for me, i.e.
dir, name = os.path.split(path)
mod = imp.load_source(name, path)
uses the .py variant even if a pyc file is available - name ends in .py under python3. The obvious solution is obviously to delete all .pyc files before loading the file - the race condition may be a problem though if you run more than one instance of your program.
One other possibility: Iirc you can let python interpret files from memory - i.e. load the file with the normal file API and then compile the in-memory variant. Something like:
path = "some Filepath.py"
with open(path, "r", encoding="utf-8") as file:
data = file.read()
exec(compile(data, "<string>", "exec")) # fair use of exec, that's a first!
How about using zip files containing python sources instead:
import sys
sys.path.insert("package.zip")
You could mark the directories containing the .py files as read-only.

Categories