8000 bpo-46303: Move fileutils.h private functions to internal C API by vstinner · Pull Request #30484 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-46303: Move fileutils.h private functions to internal C API #30484

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 1 addition & 159 deletions Include/cpython/fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,165 +2,7 @@
# error "this header file must not be included directly"
#endif

typedef enum {
_Py_ERROR_UNKNOWN=0,
_Py_ERROR_STRICT,
_Py_ERROR_SURROGATEESCAPE,
_Py_ERROR_REPLACE,
_Py_ERROR_IGNORE,
_Py_ERROR_BACKSLASHREPLACE,
_Py_ERROR_SURROGATEPASS,
_Py_ERROR_XMLCHARREFREPLACE,
_Py_ERROR_OTHER
} _Py_error_handler;

PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors);

PyAPI_FUNC(int) _Py_DecodeLocaleEx(
const char *arg,
wchar_t **wstr,
size_t *wlen,
const char **reason,
int current_locale,
_Py_error_handler errors);

PyAPI_FUNC(int) _Py_EncodeLocaleEx(
const wchar_t *text,
char **str,
size_t *error_pos,
const char **reason,
int current_locale,
_Py_error_handler errors);

PyAPI_FUNC(char*) _Py_EncodeLocaleRaw(
const wchar_t *text,
size_t *error_pos);

PyAPI_FUNC(PyObject *) _Py_device_encoding(int);

#if defined(MS_WINDOWS) || defined(__APPLE__)
/* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611).
On macOS 10.13, read() and write() with more than INT_MAX bytes
fail with EINVAL (bpo-24658). */
# define _PY_READ_MAX INT_MAX
# define _PY_WRITE_MAX INT_MAX
#else
/* write() should truncate the input to PY_SSIZE_T_MAX bytes,
but it's safer to do it ourself to have a portable behaviour */
# define _PY_READ_MAX PY_SSIZE_T_MAX
# define _PY_WRITE_MAX PY_SSIZE_T_MAX
#endif

#ifdef MS_WINDOWS
struct _Py_stat_struct {
unsigned long st_dev;
uint64_t st_ino;
unsigned short st_mode;
int st_nlink;
int st_uid;
int st_gid;
unsigned long st_rdev;
__int64 st_size;
time_t st_atime;
int st_atime_nsec;
time_t st_mtime;
int st_mtime_nsec;
time_t st_ctime;
int st_ctime_nsec;
unsigned long st_file_attributes;
unsigned long st_reparse_tag;
};
#else
# define _Py_stat_struct stat
#endif

PyAPI_FUNC(int) _Py_fstat(
int fd,
struct _Py_stat_struct *status);

PyAPI_FUNC(int) _Py_fstat_noraise(
int fd,
struct _Py_stat_struct *status);

PyAPI_FUNC(int) _Py_stat(
PyObject *path,
struct stat *status);

PyAPI_FUNC(int) _Py_open(
const char *pathname,
int flags);

PyAPI_FUNC(int) _Py_open_noraise(
const char *pathname,
int flags);

PyAPI_FUNC(FILE *) _Py_wfopen(
const wchar_t *path,
const wchar_t *mode);

// Used by _testcapi which must not use the internal C API
PyAPI_FUNC(FILE*) _Py_fopen_obj(
PyObject *path,
const char *mode);

PyAPI_FUNC(Py_ssize_t) _Py_read(
int fd,
void *buf,
size_t count);

PyAPI_FUNC(Py_ssize_t) _Py_write(
int fd,
const void *buf,
size_t count);

PyAPI_FUNC(Py_ssize_t) _Py_write_noraise(
int fd,
const void *buf,
size_t count);

#ifdef HAVE_READLINK
PyAPI_FUNC(int) _Py_wreadlink(
const wchar_t *path,
wchar_t *buf,
/* Number of characters of 'buf' buffer
including the trailing NUL character */
size_t buflen);
#endif

#ifdef HAVE_REALPATH
PyAPI_FUNC(wchar_t*) _Py_wrealpath(
const wchar_t *path,
wchar_t *resolved_path,
/* Number of characters of 'resolved_path' buffer
including the trailing NUL character */
size_t resolved_path_len);
#endif

PyAPI_FUNC(wchar_t*) _Py_wgetcwd(
wchar_t *buf,
/* Number of characters of 'buf' buffer
including the trailing NUL character */
size_t buflen);

PyAPI_FUNC(int) _Py_get_inheritable(int fd);

PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable,
int *atomic_flag_works);

PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable,
int *atomic_flag_works);

PyAPI_FUNC(int) _Py_dup(int fd);

#ifndef MS_WINDOWS
PyAPI_FUNC(int) _Py_get_blocking(int fd);

PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking);
#else /* MS_WINDOWS */
PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd);

PyAPI_FUNC(void*) _Py_get_osfhandle(int fd);

PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags);

PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags);
#endif /* MS_WINDOWS */
159 changes: 159 additions & 0 deletions Include/internal/pycore_fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,165 @@ extern "C" {

#include <locale.h> /* struct lconv */

typedef enum {
_Py_ERROR_UNKNOWN=0,
_Py_ERROR_STRICT,
_Py_ERROR_SURROGATEESCAPE,
_Py_ERROR_REPLACE,
_Py_ERROR_IGNORE,
_Py_ERROR_BACKSLASHREPLACE,
_Py_ERROR_SURROGATEPASS,
_Py_ERROR_XMLCHARREFREPLACE,
_Py_ERROR_OTHER
} _Py_error_handler;

PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors);

PyAPI_FUNC(int) _Py_DecodeLocaleE 8000 x(
const char *arg,
wchar_t **wstr,
size_t *wlen,
const char **reason,
int current_locale,
_Py_error_handler errors);

PyAPI_FUNC(int) _Py_EncodeLocaleEx(
const wchar_t *text,
char **str,
size_t *error_pos,
const char **reason,
int current_locale,
_Py_error_handler errors);

PyAPI_FUNC(char*) _Py_EncodeLocaleRaw(
const wchar_t *text,
size_t *error_pos);

PyAPI_FUNC(PyObject *) _Py_device_encoding(int);

#if defined(MS_WINDOWS) || defined(__APPLE__)
/* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611).
On macOS 10.13, read() and write() with more than INT_MAX bytes
fail with EINVAL (bpo-24658). */
# define _PY_READ_MAX INT_MAX
# define _PY_WRITE_MAX INT_MAX
#else
/* write() should truncate the input to PY_SSIZE_T_MAX bytes,
but it's safer to do it ourself to have a portable behaviour */
# define _PY_READ_MAX PY_SSIZE_T_MAX
# define _PY_WRITE_MAX PY_SSIZE_T_MAX
#endif

#ifdef MS_WINDOWS
struct _Py_stat_struct {
unsigned long st_dev;
uint64_t st_ino;
unsigned short st_mode;
int st_nlink;
int st_uid;
int st_gid;
unsigned long st_rdev;
__int64 st_size;
time_t st_atime;
int st_atime_nsec;
time_t st_mtime;
int st_mtime_nsec;
time_t st_ctime;
int st_ctime_nsec;
unsigned long st_file_attributes;
unsigned long st_reparse_tag;
};
#else
# define _Py_stat_struct stat
#endif

PyAPI_FUNC(int) _Py_fstat(
int fd,
struct _Py_stat_struct *status);

PyAPI_FUNC(int) _Py_fstat_noraise(
int fd,
struct _Py_stat_struct *status);

PyAPI_FUNC(int) _Py_stat(
PyObject *path,
struct stat *status);

PyAPI_FUNC(int) _Py_open(
const char *pathname,
int flags);

PyAPI_FUNC(int) _Py_open_noraise(
const char *pathname,
int flags);

PyAPI_FUNC(FILE *) _Py_wfopen(
const wchar_t *path,
const wchar_t *mode);

PyAPI_FUNC(Py_ssize_t) _Py_read(
int fd,
void *buf,
size_t count);

PyAPI_FUNC(Py_ssize_t) _Py_write(
int fd,
const void *buf,
size_t count);

PyAPI_FUNC(Py_ssize_t) _Py_write_noraise(
int fd,
const void *buf,
size_t count);

#ifdef HAVE_READLINK
PyAPI_FUNC(int) _Py_wreadlink(
const wchar_t *path,
wchar_t *buf,
/* Number of characters of 'buf' buffer
including the trailing NUL character */
size_t buflen);
#endif

#ifdef HAVE_REALPATH
PyAPI_FUNC(wchar_t*) _Py_wrealpath(
const wchar_t *path,
wchar_t *resolved_path,
/* Number of characters of 'resolved_path' buffer
including the trailing NUL character */
size_t resolved_path_len);
#endif

PyAPI_FUNC(wchar_t*) _Py_wgetcwd(
wchar_t *buf,
/* Number of characters of 'buf' buffer
including the trailing NUL character */
size_t buflen);

PyAPI_FUNC(int) _Py_get_inheritable(int fd);

PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable,
int *atomic_flag_works);

PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable,
int *atomic_flag_works);

PyAPI_FUNC(int) _Py_dup(int fd);

#ifndef MS_WINDOWS
PyAPI_FUNC(int) _Py_get_blocking(int fd);

PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking);
#else /* MS_WINDOWS */
PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd);

PyAPI_FUNC(void*) _Py_get_osfhandle(int fd);

PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags);

PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags);
#endif /* MS_WINDOWS */

// This is used after getting NULL back from Py_DecodeLocale().
#define DECODE_LOCALE_ERR(NAME, LEN) \
((LEN) == (size_t)-2) \
Expand Down
2 changes: 2 additions & 0 deletions Include/internal/pycore_unicodeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

#include "pycore_fileutils.h" // _Py_error_handler


/* runtime lifecycle */

Expand Down
10 changes: 7 additions & 3 deletions Lib/test/test_codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
import _testcapi
except ImportError:
_testcapi = None
try:
import _testinternalcapi
except ImportError:
_testinternalcapi = None

try:
import ctypes
Expand Down Expand Up @@ -3345,7 +3349,7 @@ def test_seeking_write(self):
self.assertEqual(sr.readline(), b'789\n')


@unittest.skipIf(_testcapi is None, 'need _testcapi module')
@unittest.skipIf(_testinternalcapi is None, 'need _testinternalcapi module')
class LocaleCodecTest(unittest.TestCase):
"""
Test indirectly _Py_DecodeUTF8Ex() and _Py_EncodeUTF8Ex().
Expand All @@ -3359,7 +3363,7 @@ class LocaleCodecTest(unittest.TestCase):
SURROGATES = "\uDC80\uDCFF"

def encode(self, text, errors="strict"):
return _testcapi.EncodeLocaleEx(text, 0, errors)
return _testinternalcapi.EncodeLocaleEx(text, 0, errors)

def check_encode_strings(self, errors):
for text in self.STRINGS:
Expand Down Expand Up @@ -3399,7 +3403,7 @@ def test_encode_unsupported_error_handler(self):
self.assertEqual(str(cm.exception), 'unsupported error handler')

def decode(self, encoded, errors="strict"):
return _testcapi.DecodeLocaleEx(encoded, 0, errors)
return _testinternalcapi.DecodeLocaleEx(encoded, 0, errors)

def check_decode_strings(self, errors):
is_utf8 = (self.ENCODING == "utf-8")
Expand Down
Loading
0