comparison Python/pythonrun.c @ 65348:453fd8182c2f

Use locale encoding if Py_FileSystemDefaultEncoding is not set * PyUnicode_EncodeFSDefault(), PyUnicode_DecodeFSDefaultAndSize() and PyUnicode_DecodeFSDefault() use the locale encoding instead of UTF-8 if Py_FileSystemDefaultEncoding is NULL * redecode_filenames() functions and _Py_code_object_list (issue #9630) are no more needed: remove them
author Victor Stinner <victor.stinner@haypocalc.com>
date Fri, 15 Oct 2010 12:04:23 +0000
parents f63d747622bd
children 55ed5c524428
comparison
equal deleted inserted replaced
65347:f63d747622bd 65348:453fd8182c2f
717 Py_FatalError("can't add __builtins__ to __main__"); 717 Py_FatalError("can't add __builtins__ to __main__");
718 Py_DECREF(bimod); 718 Py_DECREF(bimod);
719 } 719 }
720 } 720 }
721 721
722 /* Redecode a filename from the default filesystem encoding (utf-8) to
723 'new_encoding' encoding with 'errors' error handler */
724 static PyObject*
725 redecode_filename(PyObject *file, const char *new_encoding,
726 const char *errors)
727 {
728 PyObject *file_bytes, *new_file;
729
730 file_bytes = PyUnicode_EncodeFSDefault(file);
731 if (file_bytes == NULL)
732 return NULL;
733 new_file = PyUnicode_Decode(
734 PyBytes_AsString(file_bytes),
735 PyBytes_GET_SIZE(file_bytes),
736 new_encoding,
737 errors);
738 Py_DECREF(file_bytes);
739 return new_file;
740 }
741
742 /* Redecode a path list */
743 static int
744 redecode_path_list(PyObject *paths,
745 const char *new_encoding, const char *errors)
746 {
747 PyObject *filename, *new_filename;
748 Py_ssize_t i, size;
749
750 size = PyList_Size(paths);
751 for (i=0; i < size; i++) {
752 filename = PyList_GetItem(paths, i);
753 if (filename == NULL)
754 return -1;
755
756 new_filename = redecode_filename(filename, new_encoding, errors);
757 if (new_filename == NULL)
758 return -1;
759 if (PyList_SetItem(paths, i, new_filename)) {
760 Py_DECREF(new_filename);
761 return -1;
762 }
763 }
764 return 0;
765 }
766
767 /* Redecode __file__ and __path__ attributes of sys.modules */
768 static int
769 redecode_sys_modules(const char *new_encoding, const char *errors)
770 {
771 PyInterpreterState *interp;
772 PyObject *modules, *values, *file, *new_file, *paths;
773 PyObject *iter = NULL, *module = NULL;
774
775 interp = PyThreadState_GET()->interp;
776 modules = interp->modules;
777
778 values = PyObject_CallMethod(modules, "values", "");
779 if (values == NULL)
780 goto error;
781
782 iter = PyObject_GetIter(values);
783 Py_DECREF(values);
784 if (iter == NULL)
785 goto error;
786
787 while (1)
788 {
789 module = PyIter_Next(iter);
790 if (module == NULL) {
791 if (PyErr_Occurred())
792 goto error;
793 else
794 break;
795 }
796
797 file = PyModule_GetFilenameObject(module);
798 if (file != NULL) {
799 new_file = redecode_filename(file, new_encoding, errors);
800 Py_DECREF(file);
801 if (new_file == NULL)
802 goto error;
803 if (PyObject_SetAttrString(module, "__file__", new_file)) {
804 Py_DECREF(new_file);
805 goto error;
806 }
807 Py_DECREF(new_file);
808 }
809 else
810 PyErr_Clear();
811
812 paths = PyObject_GetAttrString(module, "__path__");
813 if (paths != NULL) {
814 if (redecode_path_list(paths, new_encoding, errors))
815 goto error;
816 }
817 else
818 PyErr_Clear();
819
820 Py_CLEAR(module);
821 }
822 Py_CLEAR(iter);
823 return 0;
824
825 error:
826 Py_XDECREF(iter);
827 Py_XDECREF(module);
828 return -1;
829 }
830
831 /* Redecode sys.path_importer_cache keys */
832 static int
833 redecode_sys_path_importer_cache(const char *new_encoding, const char *errors)
834 {
835 PyObject *path_importer_cache, *items, *item, *path, *importer, *new_path;
836 PyObject *new_cache = NULL, *iter = NULL;
837
838 path_importer_cache = PySys_GetObject("path_importer_cache");
839 if (path_importer_cache == NULL)
840 goto error;
841
842 items = PyObject_CallMethod(path_importer_cache, "items", "");
843 if (items == NULL)
844 goto error;
845
846 iter = PyObject_GetIter(items);
847 Py_DECREF(items);
848 if (iter == NULL)
849 goto error;
850
851 new_cache = PyDict_New();
852 if (new_cache == NULL)
853 goto error;
854
855 while (1)
856 {
857 item = PyIter_Next(iter);
858 if (item == NULL) {
859 if (PyErr_Occurred())
860 goto error;
861 else
862 break;
863 }
864 path = PyTuple_GET_ITEM(item, 0);
865 importer = PyTuple_GET_ITEM(item, 1);
866
867 new_path = redecode_filename(path, new_encoding, errors);
868 if (new_path == NULL)
869 goto error;
870 if (PyDict_SetItem(new_cache, new_path, importer)) {
871 Py_DECREF(new_path);
872 goto error;
873 }
874 Py_DECREF(new_path);
875 }
876 Py_CLEAR(iter);
877 if (PySys_SetObject("path_importer_cache", new_cache))
878 goto error;
879 Py_CLEAR(new_cache);
880 return 0;
881
882 error:
883 Py_XDECREF(iter);
884 Py_XDECREF(new_cache);
885 return -1;
886 }
887
888 /* Redecode co_filename attribute of all code objects */
889 static int
890 redecode_code_objects(const char *new_encoding, const char *errors)
891 {
892 Py_ssize_t i, len;
893 PyCodeObject *co;
894 PyObject *ref, *new_file;
895
896 len = Py_SIZE(_Py_code_object_list);
897 for (i=0; i < len; i++) {
898 ref = PyList_GET_ITEM(_Py_code_object_list, i);
899 co = (PyCodeObject *)PyWeakref_GetObject(ref);
900 if ((PyObject*)co == Py_None)
901 continue;
902 if (co == NULL)
903 return -1;
904
905 new_file = redecode_filename(co->co_filename, new_encoding, errors);
906 if (new_file == NULL)
907 return -1;
908 Py_DECREF(co->co_filename);
909 co->co_filename = new_file;
910 }
911 Py_CLEAR(_Py_code_object_list);
912 return 0;
913 }
914
915 /* Redecode the filenames of all modules (__file__ and __path__ attributes),
916 all code objects (co_filename attribute), sys.path, sys.meta_path,
917 sys.executable and sys.path_importer_cache (keys) when the filesystem
918 encoding changes from the default encoding (utf-8) to new_encoding */
919 static int
920 redecode_filenames(const char *new_encoding)
921 {
922 char *errors;
923 PyObject *paths, *executable, *new_executable;
924
925 /* PyUnicode_DecodeFSDefault() and PyUnicode_EncodeFSDefault() do already
926 use utf-8 if Py_FileSystemDefaultEncoding is NULL */
927 if (strcmp(new_encoding, "utf-8") == 0)
928 return 0;
929
930 if (strcmp(new_encoding, "mbcs") != 0)
931 errors = "surrogateescape";
932 else
933 errors = NULL;
934
935 /* sys.modules */
936 if (redecode_sys_modules(new_encoding, errors))
937 return -1;
938
939 /* sys.path and sys.meta_path */
940 paths = PySys_GetObject("path");
941 if (paths != NULL) {
942 if (redecode_path_list(paths, new_encoding, errors))
943 return -1;
944 }
945 paths = PySys_GetObject("meta_path");
946 if (paths != NULL) {
947 if (redecode_path_list(paths, new_encoding, errors))
948 return -1;
949 }
950
951 /* sys.executable */
952 executable = PySys_GetObject("executable");
953 if (executable == NULL)
954 return -1;
955 new_executable = redecode_filename(executable, new_encoding, errors);
956 if (new_executable == NULL)
957 return -1;
958 if (PySys_SetObject("executable", new_executable)) {
959 Py_DECREF(new_executable);
960 return -1;
961 }
962 Py_DECREF(new_executable);
963
964 /* sys.path_importer_cache */
965 if (redecode_sys_path_importer_cache(new_encoding, errors))
966 return -1;
967
968 /* code objects */
969 if (redecode_code_objects(new_encoding, errors))
970 return -1;
971
972 return 0;
973 }
974
975 static void 722 static void
976 initfsencoding(void) 723 initfsencoding(void)
977 { 724 {
978 PyObject *codec; 725 PyObject *codec;
979 #if defined(HAVE_LANGINFO_H) && defined(CODESET) 726 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
985 Python codec, and Py_FileSystemDefaultEncoding isn't 732 Python codec, and Py_FileSystemDefaultEncoding isn't
986 initialized by other means. Also set the encoding of 733 initialized by other means. Also set the encoding of
987 stdin and stdout if these are terminals. */ 734 stdin and stdout if these are terminals. */
988 codeset = get_codeset(); 735 codeset = get_codeset();
989 if (codeset != NULL) { 736 if (codeset != NULL) {
990 if (redecode_filenames(codeset))
991 Py_FatalError("Py_Initialize: can't redecode filenames");
992 Py_FileSystemDefaultEncoding = codeset; 737 Py_FileSystemDefaultEncoding = codeset;
993 Py_HasFileSystemDefaultEncoding = 0; 738 Py_HasFileSystemDefaultEncoding = 0;
994 Py_CLEAR(_Py_code_object_list);
995 return; 739 return;
996 } else { 740 } else {
997 fprintf(stderr, "Unable to get the locale encoding:\n"); 741 fprintf(stderr, "Unable to get the locale encoding:\n");
998 PyErr_Print(); 742 PyErr_Print();
999 } 743 }
1001 fprintf(stderr, "Unable to get the filesystem encoding: fallback to utf-8\n"); 745 fprintf(stderr, "Unable to get the filesystem encoding: fallback to utf-8\n");
1002 Py_FileSystemDefaultEncoding = "utf-8"; 746 Py_FileSystemDefaultEncoding = "utf-8";
1003 Py_HasFileSystemDefaultEncoding = 1; 747 Py_HasFileSystemDefaultEncoding = 1;
1004 } 748 }
1005 #endif 749 #endif
1006
1007 Py_CLEAR(_Py_code_object_list);
1008 750
1009 /* the encoding is mbcs, utf-8 or ascii */ 751 /* the encoding is mbcs, utf-8 or ascii */
1010 codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); 752 codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding);
1011 if (!codec) { 753 if (!codec) {
1012 /* Such error can only occurs in critical situations: no more 754 /* Such error can only occurs in critical situations: no more