PyPy file append mode

2024/10/5 5:13:31

I have code like this:

f1 = open('file1', 'a')
f2 = open('file1', 'a')f1.write('Test line 1\n')
f2.write('Test line 2\n')
f1.write('Test line 3\n')
f2.write('Test line 4\n')

When this code is run with standard Python 2.7 interpreter, the file contains four lines as expected. However, when I run this code under PyPy, the file contains only two lines.

Could someone explain the differences between Python and PyPy in working with files in append mode?

UPDATED: The problem doesn't exist in the PyPy 2.3.

Answer

The reason in different behavior is different implementation of file I/O operations.

CPython implements it's file I/O on top of fopen, fread and fwrite functions from stdio.h and is working with FILE * streams.

In the same time PyPy implements it's file I/O on top of POSIX open, write and read functions and is working with int file descriptors.

Compare these two programs in C:

#include <stdio.h>int main() {FILE *a = fopen("file1", "a");FILE *b = fopen("file1", "a");fwrite("Test line 1\n", 12, 1, a);fflush(a);fwrite("Test line 2\n", 12, 1, b);fflush(b);fwrite("Test line 3\n", 12, 1, a);fflush(a);fwrite("Test line 4\n", 12, 1, b);fclose(a);fclose(b);return 0;
}

and

#include <fcntl.h>
#include <unistd.h>int main() {int a = open("file1", O_CREAT | O_WRONLY | O_APPEND);int b = open("file1", O_CREAT | O_WRONLY | O_APPEND);write(a, "Test line 1\n", 12);write(b, "Test line 2\n", 12);write(a, "Test line 3\n", 12);write(b, "Test line 4\n", 12);close(a);close(b);return 0;
}

More info on difference between open and fopen you could find in answers to this question.

UPDATE:

After inspecting PyPy codebase some more, it seems to me it doesn't use O_APPEND flag by some reason, but O_WRONLY | O_CREAT for "a" mode. So it is the real reason in PyPy you need to seek to the end of file after each write call, as J.F. Sebastian mentioned in another answer. I guess a bug should be created at PyPy bugtracker, as O_APPEND flag is available both on Windows and Unix. So, what PyPy does now looks like:

#include <fcntl.h>
#include <unistd.h>int main() {int a = open("file1", O_CREAT | O_WRONLY);int b = open("file1", O_CREAT | O_WRONLY);write(a, "Test line 1\n", 12);write(b, "Test line 2\n", 12);write(a, "Test line 3\n", 12);write(b, "Test line 4\n", 12);close(a);close(b);return 0;
}

Without O_APPEND flag it should reproduce PyPy behavior.

https://en.xdnf.cn/q/70521.html

Related Q&A

Clean up ugly WYSIWYG HTML code? Python or *nix utility

Im finally upgrading (rewriting ;) ) my first Django app, but I am migrating all the content. I foolishly gave users a full WYSIWYG editor for certain tasks, the HTML code produced is of course terribl…

Using config files written in Python [closed]

Closed. This question is opinion-based. It is not currently accepting answers.Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.Clo…

Model not defined when using foreign key to second model

Im trying to create several relationships between some models such as User and Country. When I try to syncdb, my console outputs "Name Country is not defined". Here is the code: class User(mo…

Sending a POST request to my RESTful API(Python-Flask), but receiving a GET request

Im trying to send a trigger to a Zapier webhook in the form of a POST request containing JSON. It works fine if I just send the POST request through a local python script.What I want to do is create a …

django deploy to Heroku : Server Error(500)

I am trying to deploy my app to heroku. Deploy was done correctly but I got Server Error(500). When I turned DEBUG true, Sever Error doesnt occurred. So I think there is something wrong with loading st…

Should I preallocate a numpy array?

I have a class and its method. The method repeats many times during execution. This method uses a numpy array as a temporary buffer. I dont need to store values inside the buffer between method calls. …

dup, dup2, tmpfile and stdout in python

This is a follow up question from here.Where I want do go I would like to be able to temporarily redirect the stdout into a temp file, while python still is able to print to stdout. This would involve …

How do I write a Class-Based Django Validator?

Im using Django 1.8.The documentation on writing validators has an example of a function-based validator. It also says the following on using a class:You can also use a class with a __call__() method f…

python synthesize midi with fluidsynth

I cant import fluidsynth. [Maybe theres an better module?]Im trying to synthesize midi from python or pygame. I can send midi events from pygame. Im using mingus, and it seemed pyfluidsynth would be g…

Convenient way to handle deeply nested dictionary in Python

I have a deeply nested dictionary in python thats taking up a lot of room. Is there a way to abbreviate something like this master_dictionary[sub_categories][sub_cat_name][attributes][attribute_name][s…