| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 75a902d commit ce3a72a
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2425,6 +2425,12 @@ change in future releases of Python. | |||
| 2425 | 2425 | pointer, *fp*. The function *close* will be called when the file should be | |
| 2426 | 2426 | closed. Return *NULL* on failure. | |
| 2427 | 2427 | ||
| 2428 | + .. cfunction:: PyFile_FromFileEx(FILE *fp, char *name, char *mode, int (*close)(FILE *), int buffering, char *encoding, char *newline) | ||
| 2429 | + | ||
| 2430 | + Create a new :ctype:`PyFileObject` from the already-open standard C file | ||
| 2431 | + pointer, *fp*. The functions works similar to *PyFile_FromFile* but takes | ||
| 2432 | + optional arguments for *buffering*, *encoding* and *newline*. Use -1 resp. | ||
| 2433 | + *NULL* for default values. | ||
| 2428 | 2434 | ||
| 2429 | 2435 | .. cfunction:: FILE* PyFile_AsFile(PyObject *p) | |
| 2430 | 2436 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -338,6 +338,15 @@ PyFile_FromFile:char*:name:: | |||
| 338 | 338 | PyFile_FromFile:char*:mode:: | |
| 339 | 339 | PyFile_FromFile:int(*:close):: | |
| 340 | 340 | ||
| 341 | + PyFile_FromFileEx:PyObject*::+1: | ||
| 342 | + PyFile_FromFileEx:FILE*:fp:: | ||
| 343 | + PyFile_FromFileEx:char*:name:: | ||
| 344 | + PyFile_FromFileEx:char*:mode:: | ||
| 345 | + PyFile_FromFileEx:int(*:close):: | ||
| 346 | + PyFile_FromFileEx:int:buffering:: | ||
| 347 | + PyFile_FromFileEx:char*:encoding:: | ||
| 348 | + PyFile_FromFileEx:char*:newline:: | ||
| 349 | + | ||
| 341 | 350 | PyFile_FromString:PyObject*::+1: | |
| 342 | 351 | PyFile_FromString:char*:name:: | |
| 343 | 352 | PyFile_FromString:char*:mode:: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,6 +9,9 @@ extern "C" { | |||
| 9 | 9 | #define PY_STDIOTEXTMODE "b" | |
| 10 | 10 | ||
| 11 | 11 | PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *, int (*)(FILE*)); | |
| 12 | + PyAPI_FUNC(PyObject *) PyFile_FromFileEx(FILE *, char *, char *, | ||
| 13 | + int (*)(FILE *), int, char *, | ||
| 14 | + char *); | ||
| 12 | 15 | PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); | |
| 13 | 16 | PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); | |
| 14 | 17 | PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -178,6 +178,18 @@ def open(file, mode="r", buffering=None, encoding=None, newline=None): | |||
| 178 | 178 | return text | |
| 179 | 179 | ||
| 180 | 180 | ||
| 181 | + class OpenWrapper: | ||
| 182 | + """Wrapper for __builtin__.open | ||
| 183 | + | ||
| 184 | + Trick so that open won't become a bound method when stored | ||
| 185 | + as a class variable (as dumbdbm does). | ||
| 186 | + | ||
| 187 | + See initstdio() in Python/pythonrun.c. | ||
| 188 | + """ | ||
| 189 | + def __new__(cls, *args, **kwargs): | ||
| 190 | + return open(*args, **kwargs) | ||
| 191 | + | ||
| 192 | + | ||
| 181 | 193 | class UnsupportedOperation(ValueError, IOError): | |
| 182 | 194 | pass | |
| 183 | 195 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -402,23 +402,6 @@ def execsitecustomize(): | |||
| 402 | 402 | (err.__class__.__name__, err)) | |
| 403 | 403 | ||
| 404 | 404 | ||
| 405 | - def installnewio(): | ||
| 406 | - """Install new I/O library as default.""" | ||
| 407 | - import io | ||
| 408 | - # Hack to avoid a nasty recursion issue when Python is invoked | ||
| 409 | - # in verbose mode: pre-import the Latin-1 and UTF-8 codecs | ||
| 410 | - from encodings import latin_1, utf_8 | ||
| 411 | - # Trick so that open won't become a bound method when stored | ||
| 412 | - # as a class variable (as dumbdbm does) | ||
| 413 | - class open: | ||
| 414 | - def __new__(cls, *args, **kwds): | ||
| 415 | - return io.open(*args, **kwds) | ||
| 416 | - __builtin__.open = open | ||
| 417 | - sys.__stdin__ = sys.stdin = io.open(0, "r", newline='\n') | ||
| 418 | - sys.__stdout__ = sys.stdout = io.open(1, "w", newline='\n') | ||
| 419 | - sys.__stderr__ = sys.stderr = io.open(2, "w", newline='\n') | ||
| 420 | - | ||
| 421 | - | ||
| 422 | 405 | def main(): | |
| 423 | 406 | abs__file__() | |
| 424 | 407 | paths_in_sys = removeduppaths() | |
@@ -433,7 +416,6 @@ def main(): | |||
| 433 | 416 | sethelper() | |
| 434 | 417 | aliasmbcs() | |
| 435 | 418 | setencoding() | |
| 436 | - installnewio() | ||
| 437 | 419 | execsitecustomize() | |
| 438 | 420 | # Remove sys.setdefaultencoding() so that users cannot change the | |
| 439 | 421 | # encoding after initialization. The test for presence is needed when | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,9 +38,16 @@ def testLock(self): | |||
| 38 | 38 | self.fail("release_lock() without lock should raise " | |
| 39 | 39 | "RuntimeError") | |
| 40 | 40 | ||
| 41 | + class ImportTests(unittest.TestCase): | ||
| 42 | + | ||
| 43 | + def test_find_module_encoding(self): | ||
| 44 | + fd = imp.find_module("heapq")[0] | ||
| 45 | + self.assertEqual(fd.encoding, "iso-8859-1") | ||
| 46 | + | ||
| 41 | 47 | def test_main(): | |
| 42 | 48 | test_support.run_unittest( | |
| 43 | 49 | LockTests, | |
| 50 | + ImportTests, | ||
| 44 | 51 | ) | |
| 45 | 52 | ||
| 46 | 53 | if __name__ == "__main__": | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,22 +28,32 @@ extern "C" { | |||
| 28 | 28 | PyObject * | |
| 29 | 29 | PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *)) | |
| 30 | 30 | { | |
| 31 | - PyObject *io, *stream, *nameobj; | ||
| 31 | + return PyFile_FromFileEx(fp, name, mode, close, -1, NULL, NULL); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + PyObject * | ||
| 35 | + PyFile_FromFileEx(FILE *fp, char *name, char *mode, int (*close)(FILE *), | ||
| 36 | + int buffering, char *encoding, char *newline) | ||
| 37 | + { | ||
| 38 | + PyObject *io, *stream, *nameobj=NULL; | ||
| 32 | 39 | ||
| 33 | 40 | io = PyImport_ImportModule("io"); | |
| 34 | 41 | if (io == NULL) | |
| 35 | 42 | return NULL; | |
| 36 | - stream = PyObject_CallMethod(io, "open", "is", fileno(fp), mode); | ||
| 37 | - Py_DECREF(io); | ||
| 43 | + stream = PyObject_CallMethod(io, "open", "isiss", fileno(fp), mode, | ||
| 44 | + buffering, encoding, newline); | ||
| 45 | + Py_DECREF(io); | ||
| 38 | 46 | if (stream == NULL) | |
| 39 | 47 | return NULL; | |
| 40 | - nameobj = PyUnicode_FromString(name); | ||
| 41 | - if (nameobj == NULL) | ||
| 42 | - PyErr_Clear(); | ||
| 43 | - else { | ||
| 44 | - if (PyObject_SetAttrString(stream, "name", nameobj) < 0) | ||
| 48 | + if (name != NULL) { | ||
| 49 | + nameobj = PyUnicode_FromString(name); | ||
| 50 | + if (nameobj == NULL) | ||
| 45 | 51 | PyErr_Clear(); | |
| 46 | - Py_DECREF(nameobj); | ||
| 52 | + else { | ||
| 53 | + if (PyObject_SetAttrString(stream, "name", nameobj) < 0) | ||
| 54 | + PyErr_Clear(); | ||
| 55 | + Py_DECREF(nameobj); | ||
| 56 | + } | ||
| 47 | 57 | } | |
| 48 | 58 | return stream; | |
| 49 | 59 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1601,7 +1601,28 @@ PyTokenizer_RestoreEncoding(struct tok_state* tok, int len, int *offset) | |||
| 1601 | 1601 | } | |
| 1602 | 1602 | #endif | |
| 1603 | 1603 | ||
| 1604 | - | ||
| 1604 | + /* Get -*- encoding -*- from a Python file | ||
| 1605 | + | ||
| 1606 | + PyTokenizer_FindEncoding returns NULL when it can't find the encoding in | ||
| 1607 | + the first or second line of the file. In this case the encoding is | ||
| 1608 | + PyUnicode_GetDefaultEncoding(). | ||
| 1609 | + */ | ||
| 1610 | + char * | ||
| 1611 | + PyTokenizer_FindEncoding(FILE *fp) { | ||
| 1612 | + struct tok_state *tok; | ||
| 1613 | + char *p_start=NULL, *p_end=NULL; | ||
| 1614 | + | ||
| 1615 | + if ((tok = PyTokenizer_FromFile(fp, NULL, NULL, NULL)) == NULL) { | ||
| 1616 | + rewind(fp); | ||
| 1617 | + return NULL; | ||
| 1618 | + } | ||
| 1619 | + while(((tok->lineno <= 2) && (tok->done == E_OK))) { | ||
| 1620 | + PyTokenizer_Get(tok, &p_start, &p_end); | ||
| 1621 | + } | ||
| 1622 | + | ||
| 1623 | + rewind(fp); | ||
| 1624 | + return tok->encoding; | ||
| 1625 | + } | ||
| 1605 | 1626 | ||
| 1606 | 1627 | #ifdef Py_DEBUG | |
| 1607 | 1628 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -67,6 +67,7 @@ extern void PyTokenizer_Free(struct tok_state *); | |||
| 67 | 67 | extern int PyTokenizer_Get(struct tok_state *, char **, char **); | |
| 68 | 68 | extern char * PyTokenizer_RestoreEncoding(struct tok_state* tok, | |
| 69 | 69 | int len, int *offset); | |
| 70 | + extern char * PyTokenizer_FindEncoding(FILE *fp); | ||
| 70 | 71 | ||
| 71 | 72 | #ifdef __cplusplus | |
| 72 | 73 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -91,6 +91,9 @@ static PyObject *extensions = NULL; | |||
| 91 | 91 | /* This table is defined in config.c: */ | |
| 92 | 92 | extern struct _inittab _PyImport_Inittab[]; | |
| 93 | 93 | ||
| 94 | + /* Method from Parser/tokenizer.c */ | ||
| 95 | + extern char * PyTokenizer_FindEncoding(FILE *fp); | ||
| 96 | + | ||
| 94 | 97 | struct _inittab *PyImport_Inittab = _PyImport_Inittab; | |
| 95 | 98 | ||
| 96 | 99 | /* these tables define the module suffixes that Python recognizes */ | |
@@ -2558,6 +2561,7 @@ call_find_module(char *name, PyObject *path) | |||
| 2558 | 2561 | struct filedescr *fdp; | |
| 2559 | 2562 | char pathname[MAXPATHLEN+1]; | |
| 2560 | 2563 | FILE *fp = NULL; | |
| 2564 | + char *encoding = NULL; | ||
| 2561 | 2565 | ||
| 2562 | 2566 | pathname[0] = '\0'; | |
| 2563 | 2567 | if (path == Py_None) | |
@@ -2566,7 +2570,14 @@ call_find_module(char *name, PyObject *path) | |||
| 2566 | 2570 | if (fdp == NULL) | |
| 2567 | 2571 | return NULL; | |
| 2568 | 2572 | if (fp != NULL) { | |
| 2569 | - fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose); | ||
| 2573 | + if (strchr(fdp->mode, 'b') == NULL) { | ||
| 2574 | + /* Python text file, get encoding from tokenizer */ | ||
| 2575 | + encoding = PyTokenizer_FindEncoding(fp); | ||
| 2576 | + encoding = (encoding != NULL) ? encoding : | ||
| 2577 | + (char*)PyUnicode_GetDefaultEncoding(); | ||
| 2578 | + } | ||
| 2579 | + fob = PyFile_FromFileEx(fp, pathname, fdp->mode, fclose, -1, | ||
| 2580 | + (char*)encoding, NULL); | ||
| 2570 | 2581 | if (fob == NULL) { | |
| 2571 | 2582 | fclose(fp); | |
| 2572 | 2583 | return NULL; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments