Trick open() into reading from a non-file? - python-3.x

I realize this is a pretty weird thing to want to do - it's mainly just to simplify my unittests.
I have a class whose __init__ takes a filename as an argument, which it open()s and reads a bunch of data from. It'd be really awesome if I could somehow "trick" that open() into reading from a string object instead without actually writing a temporary file to disk.
Is this possible, and if so, how would I go about it?

You can monkey-patch the module that contains the class before running the test, and restore it after the test:
def my_fake_open(fake_filename):
return object_with_read_and_close_that_will_feed_correct_data()
def test_something(self):
module_containing_test.open = my_fake_open
...run test...
del module_containing_test.open
Check out the mock library if you don't want to write your own mock objects.

Reading a bit too fast, I thought the answer would be in io.stringIO which allows you to create a file-like object with the content of a string.
But what you want, is an object that, passed to the standard open function would actually yield a file-like object from the contents of the your string.
The thing is that open takes a string (or a file descriptor) but anything else will pause a problem.
So I don't believe this way is practical.
But actually, it's not difficult to create a file using tempfile:
with tempfile.NamedTemporaryFile() as tmp_file:
tmp_file.write(your_string)
yourmodule.YourClass(tmp_file.name)
(If you're on Windows you might want to play with delete=False and close before sending the name for it to be opened.)
Another approach might be to just change the API: if all the init does with the name is to open a file, why not directly pass a file-like object.

Related

How to get a filename without extension in Kotlin

What is the best way to get the filename from a String or a File object, removing the extension?
I found that creating a File object is a straightforward way to achieve this. No actual file will be created on disk. But take care that only the last extension will be removed:
File("myFile.txt").nameWithoutExtension
File("myFile.tar.gz").nameWithoutExtension
result:
"myFile"
"myFile.tar"
I can not post this as comment, so I have to post this as separate answer.
Your solution will work, but seems like a little bit overkill. Implementation of this function simply calls substringBeforeLast(".") on filename, so I suggest to use this function. By default it will return exact same string, if string has no dot, but you can override this behaviour by providing second parameter.

Using the glob module in while loop to wait for a download

I want to pause my python script while waiting for a file download to happen.
I don't want to use an explicit wait.
I want this to run fast and not rely on an explicit wait.
I'm kinda noobish but here is what I have tried.
file_check = glob.glob1('downloads', '*.pdf')
while not os.path.isfile(str(file_check)):
time.sleep(1)
I used the str() because it complained about needing a string for the path.
I have a feeling this isn't the way to properly do this. so how should I dynamically wait for a file download?
P.S
My .pdf file downloads into '/downloads', and my pdf is dynamically named before download so that's why I need globs wildcard.
When you do file_check = glob.glob1('downloads', '*.pdf') the result of glob.glob1(...) is stored in file_check just once and that's it. In this case, if you enter inside the while loop you never will get out of there because file_check will not change (except if there are threads or stuff like that that can modify their value externally).
glob.glob and glob.glob1 (this one it's not even public, as you can see the docs) returns a list. If 'downloads' folder it's empty, you will get an empty list []. In Python, lists have an implicit booleanness, so if the list it's empty, in a conditional statement it will be interpreted as False, or 'True' if it's not empty.
Rewriting your code the result will be something like this:
while not glob.glob1('downloads', '*.pdf'):
time.sleep(1)

In IDL, how can I access a variable given its name?

I would like to convert a string to a variablename, so it can be read as a already restored variable.
So, I look through a file, and look at all the files. I use RESTORE to use the file in IDL, restore names this object as something slightly different. It names it as an object which we'll call map_1 (in the code it's called filerestore_name). This is related to the file name and I can recreate this variable name - however, its saved as a string.
Now, I pass this onto the make_cool_video procedure. However, althoughthis string now is exactly the same as the varialbe name, its still a string!.
Thus, as its a string, the procedure can't work.
filenames=FILE_SEARCH('rxrt*')
filenames_withoutextension = STREGEX(filenames,'rxrt_[0-9]+[a-zA-Z_]+',/EXTRACT,/FOLD_CASE)
restore, '/home/tomi/Documents/actualwork/'+filenames_withoutextension(18)+'.idl_sav',
filerestore_name = STRJOIN(STRSPLIT(filenameswithout(18),'_[0-9]+',/EXTRACT,/REGEX),'')
PRINT, filerestorename
make_cool_video, EXECUTE(filerestore_name),filename=filerestorenames, outdir='/path/to.file/'
retall
What I tried: using the RESTORE function and the associated RESTORED_OBJECTS to store pointers in an array, and then referring to the array. But I couldn't get the restore function to form an array.
Using EXECUTE(filerestore_name) however, this doesn't convert it as I was expecting.
I would recommend using SCOPE_VARFETCH() instead (it isn't as limited as EXECUTE() and is probably more efficient). You can do something like:
make_cool_video, (SCOPE_VARFETCH(filerestore_name)), filename=filerestorenames, outdir='/path/to.file/'
I wrote this, then immediately thought of the answer.
So,
Convert everything to a string:
string1 = "makecooljes, "+ filerestore_name, outdir='file/to/path/'"
result= EXECUTE(string1)

Copy and transform a file using Node.js

I want to copy some files using Node.js. Basically, this is quite easy, but I have two special requirements I need to fulfill:
I need to parse the file's content and replace some placeholders by actual values.
The file name may include a placeholder as well, and I need to replace this as well with an actual value.
So, while this is not a complex task basically, I guess there are various ways how you could solve this. E.g., it would be nice if I could use a template engine to do the replacements, but on the other hand then I need to have the complete file as a string. I'd prefer a stream-based approach, but then - how should I do the replacing?
You see, lots of questions, and I am not able to decide which way to go.
Any hints, ideas, best practices, ...?
Or - is there a module yet that does this task?
You can write your own solution without reading the entire file. fs.readFile() should only be used when you are 100% sure that the files are no longer than a buffer chunk (typically 8KB or 16KB).
The simplest solution is to create a readable stream, attach a data event listener and iterate the buffer reading character by character. If you have a placeholder like this: ${label}, then check if you find ${, then set a flag to true. Begin storing the label name. If you find } and flag is true then you've finished. Set flag to false and the temporal label string to "".
You don't need any template engine or extra module.
If the whole file can be safely loaded into memory (isn't crazy big), then the library fs-jetpack might be very good tool for this use case.
const jetpack = require("fs-jetpack");
const src = jetpack.cwd("path/to/source/folder");
const dst = jetpack.cwd("path/to/destination");
src.find({ matching: "*" }).forEach((path) => {
const content = src.read(path);
const transformedContent = transformTheFileHoweverYouWant(content);
const transformedPath = transformThePath(path);
dst.write(transformedPath, transformedContent);
});
In the example code is synchronous, but you can easily make async equivalent.

Pythonic way of closing/terminating an object

I have a Whoosh (file indexer) writer object
>>> a
<whoosh.filedb.filewriting.SegmentWriter object at 0x013DFE10>
As whoosh doesnt allow mutiple writers and implement thread safety (AFAIK!!), I would like to close that object when it has been used.
>>> a.is_closed
False
But it has no close method. I was assured that all mature python library objects have internal functions such as __ exit__ that allow all basic functionality. What is the right way of closing a Python object? Or does it depend on the library itself? I take the "a single but obvious way to do it right" way of Python in it's literal form
Here's the paste of dir(a): http://pastebin.com/Q5hceTr8
Postscript
I just learned about the with statement just a day before by asking on Confused about Python's with statement . This question is distinct because I needed a way to handle a global object; so that I can do a commit after multiple additions or deletions. Seems like whoosh has a searcher.close() but not an indexer.close(), which seems inconsistent
If it has __enter__ and __exit__ methods, that means it implements the context manager protocol, and you should use it like this:
with constructor(args) as a:
# do stuff with a
pass
# here a is closed even if you had an error above
Where constructor is either the class itself or whatever factory function you use to create it. In Python 2.5 you need to from __future__ import with_statement.
I was assured that all mature python library objects have internal functions such as __ exit__ that allow all basic functionality.
They do, and your pastebin indicates such - see __exit__ at the top?
This is a special method used to implement the following...
What is the right way of closing a Python object?
Automatically, using a with-block:
with some_api_call() as awesome_thing_from_api:
use(awesome_thing_from_api)

Resources