Skip to content

Commit 70ba7e8

Browse files
committed
Moving zip_directory_cache to ZipModuleBuiltins.
Adding checks if a zipimporter was initialized. Correcting licences.
1 parent ecfeb2b commit 70ba7e8

File tree

7 files changed

+103
-72
lines changed

7 files changed

+103
-72
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_zipimport.py

Lines changed: 29 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,28 @@
1-
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2-
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1+
# Copyright (c) 2018, Oracle and/or its affiliates.
2+
# Copyright (c) 2013, Regents of the University of California
33
#
4-
# The Universal Permissive License (UPL), Version 1.0
4+
# All rights reserved.
55
#
6-
# Subject to the condition set forth below, permission is hereby granted to any
7-
# person obtaining a copy of this software, associated documentation and/or
8-
# data (collectively the "Software"), free of charge and under any and all
9-
# copyright rights in the Software, and any and all patent rights owned or
10-
# freely licensable by each licensor hereunder covering either (i) the
11-
# unmodified Software as contributed to or provided by such licensor, or (ii)
12-
# the Larger Works (as defined below), to deal in both
6+
# Redistribution and use in source and binary forms, with or without modification, are
7+
# permitted provided that the following conditions are met:
138
#
14-
# (a) the Software, and
9+
# 1. Redistributions of source code must retain the above copyright notice, this list of
10+
# conditions and the following disclaimer.
11+
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of
12+
# conditions and the following disclaimer in the documentation and/or other materials provided
13+
# with the distribution.
1514
#
16-
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17-
# one is included with the Software each a "Larger Work" to which the Software
18-
# is contributed by such licensors),
19-
#
20-
# without restriction, including without limitation the rights to copy, create
21-
# derivative works of, display, perform, and distribute the Software and make,
22-
# use, sell, offer for sale, import, export, have made, and have sold the
23-
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24-
# either these or other terms.
25-
#
26-
# This license is subject to the following condition:
27-
#
28-
# The above copyright notice and either this complete permission notice or at a
29-
# minimum a reference to the UPL must be included in all copies or substantial
30-
# portions of the Software.
31-
#
32-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38-
# SOFTWARE.
15+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
16+
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17+
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
18+
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20+
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
21+
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23+
# OF THE POSSIBILITY OF SUCH DAMAGE.
24+
# Qunaibit 02/05/2014
25+
# With Statement
3926

4027
import sys
4128
import os
@@ -46,11 +33,9 @@
4633
import zipimport
4734
from zipimport import ZipImportError
4835

49-
5036
from test import support
5137
from zipfile import ZipFile, ZipInfo, ZIP_STORED, ZIP_DEFLATED
5238

53-
5439
test_src = """\
5540
def get_name():
5641
return __name__
@@ -63,7 +48,6 @@ def get_file():
6348
ZIP_PATH = os.path.join(DIR_PATH, ZIP_FILE_NAME)
6449
ZIP_ABS_PATH = os.path.abspath(ZIP_PATH);
6550

66-
6751
class ZipImportBaseTestCase(unittest.TestCase):
6852

6953
def setUp(self):
@@ -82,12 +66,11 @@ def tearDown(self):
8266
support.modules_cleanup(*self.modules_before)
8367

8468
class BasicZipImportTests(ZipImportBaseTestCase):
85-
69+
8670
def setUp(self):
8771
ZipImportBaseTestCase.setUp(self)
8872
self.z = zipimport.zipimporter(ZIP_PATH)
8973

90-
9174
def test_zipimporter_attribute(self):
9275
self.assertTrue(self.z.prefix == "")
9376
self.assertTrue(self.z.archive == ZIP_ABS_PATH)
@@ -98,7 +81,7 @@ def test_zipimporter_attribute(self):
9881
self.assertTrue(self.z._files["cesta/moduleA.py"] is not None)
9982

10083
def test_create_zipimport_from_string(self):
101-
zipimport._zip_directory_cache.clear()
84+
zipimport._zip_directory_cache.clear()
10285
z = zipimport.zipimporter(ZIP_PATH)
10386
self.assertTrue(zipimport._zip_directory_cache[ZIP_ABS_PATH] is not None)
10487

@@ -114,12 +97,12 @@ def __init__(self, path):
11497
self.value = path
11598
def __fspath__(self):
11699
return self.value
117-
100+
118101
zipimport._zip_directory_cache.clear()
119102
mp = MyPath(ZIP_PATH)
120103
z = zipimport.zipimporter(mp)
121104
self.assertTrue(zipimport._zip_directory_cache[os.path.abspath(ZIP_PATH)] is not None)
122-
105+
123106
def test_zipimporter_find_module(self):
124107
self.assertTrue(self.z is self.z.find_module("MyTestModule"))
125108
self.assertTrue(self.z is self.z.find_module("packageA"))
@@ -175,11 +158,11 @@ def test_zipimporter_load_module(self):
175158
self.assertTrue(self.z.load_module("packageA/moduleC").__loader__ is self.z)
176159
self.assertTrue(self.z.load_module("cesta/moduleA").__loader__ is self.z)
177160
self.assertRaises(ZipImportError, self.z.load_module, "packageA.moduleC")
178-
161+
179162
class ZipImportWithPrefixTests(ZipImportBaseTestCase):
180163

181164
def setUp(self):
182-
ZipImportBaseTestCase.setUp(self)
165+
ZipImportBaseTestCase.setUp(self)
183166
self.z = zipimport.zipimporter(ZIP_PATH + "/cesta")
184167

185168
def tearDown(self):
@@ -202,15 +185,13 @@ def test_zipimporter_with_prefix_find_module(self):
202185
self.assertTrue(self.z is self.z.find_module("moduleA"))
203186

204187
class ImportTests(ZipImportBaseTestCase):
205-
188+
206189
def setUp(self):
207190
ZipImportBaseTestCase.setUp(self)
208191
sys.path.insert(0, ZIP_PATH)
209-
192+
210193
def test_module_import(self):
211194
m = importlib.import_module("MyTestModule")
212195
self.assertTrue (m.get_file() == ZIP_ABS_PATH + "/MyTestModule.py")
213196
p = importlib.import_module("packageA.moduleC")
214197
self.assertTrue (p.get_file() == ZIP_ABS_PATH + "/packageA/moduleC.py")
215-
216-

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ private static final String[] initializeCoreFiles() {
211211
"function",
212212
"_sysconfig",
213213
"_socket",
214-
"_thread"));
214+
"_thread",
215+
"zipimport"));
215216

216217
return coreFiles.toArray(new String[coreFiles.size()]);
217218
}
@@ -304,7 +305,7 @@ private static final PythonBuiltins[] initializeBuiltins() {
304305
new CtypesModuleBuiltins(),
305306
new ReadlineModuleBuiltins(),
306307
new PyExpatModuleBuiltins(),
307-
new SysConfigModuleBuiltins()));
308+
new SysConfigModuleBuiltins(),
308309
new ZipImporterBuiltins(),
309310
new ZipImportModuleBuiltins()));
310311
if (!TruffleOptions.AOT) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ZipImportModuleBuiltins.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,27 @@
4646
import com.oracle.graal.python.builtins.CoreFunctions;
4747
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4848
import com.oracle.graal.python.builtins.PythonBuiltins;
49+
import com.oracle.graal.python.builtins.objects.dict.PDict;
50+
import com.oracle.graal.python.builtins.objects.module.PythonModule;
4951
import com.oracle.graal.python.builtins.objects.type.PythonClass;
5052
import com.oracle.graal.python.builtins.objects.zipimporter.PZipImporter;
5153
import com.oracle.graal.python.builtins.objects.zipimporter.ZipImporterBuiltins;
54+
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
5255
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5356
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
5457
import com.oracle.graal.python.runtime.PythonCore;
58+
import com.oracle.truffle.api.dsl.Cached;
5559
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5660
import com.oracle.truffle.api.dsl.NodeFactory;
5761
import com.oracle.truffle.api.dsl.Specialization;
5862

59-
@CoreFunctions(defineModule = "zipimport")
63+
@CoreFunctions(defineModule = ZipImportModuleBuiltins.ZIPIMPORT_MODULE_NAME)
6064
public class ZipImportModuleBuiltins extends PythonBuiltins {
6165

66+
protected static final String ZIPIMPORT_MODULE_NAME = "zipimport";
67+
68+
private static final String ZIP_DIRECTORY_CACHE_NAME = "_zip_directory_cache";
69+
6270
private static final String ZIPIMPORTER_DOC = "zipimporter(archivepath) -> zipimporter object\n" +
6371
"\n" +
6472
"Create a new zipimporter instance. 'archivepath' must be a path to\n" +
@@ -76,7 +84,7 @@ public ZipImportModuleBuiltins() {
7684
@Override
7785
public void initialize(PythonCore core) {
7886
super.initialize(core);
79-
builtinConstants.put("_zip_directory_cache", ZipImporterBuiltins.getCache(core.factory()));
87+
builtinConstants.put(ZIP_DIRECTORY_CACHE_NAME, core.factory().createDict());
8088

8189
}
8290

@@ -85,8 +93,10 @@ public void initialize(PythonCore core) {
8593
public abstract static class ZipImporterNode extends PythonBinaryBuiltinNode {
8694

8795
@Specialization
88-
public PZipImporter createNew(PythonClass cls, @SuppressWarnings("unused") Object path) {
89-
return factory().createZipImporter(cls);
96+
public PZipImporter createNew(PythonClass cls, @SuppressWarnings("unused") Object path,
97+
@Cached("create()") ReadAttributeFromObjectNode readNode) {
98+
PythonModule module = getCore().lookupBuiltinModule(ZIPIMPORT_MODULE_NAME);
99+
return factory().createZipImporter(cls, (PDict) readNode.execute(module, ZIP_DIRECTORY_CACHE_NAME));
90100
}
91101

92102
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/zipimporter/PZipImporter.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ public class PZipImporter extends PythonBuiltinObject {
5858
*/
5959
private PDict files;
6060

61+
/**
62+
* Cache of the files in the zipfile. Exported in ZipimportModuleBuiltins
63+
*/
64+
private final PDict moduleZipDirectoryCache;
65+
6166
/**
6267
* Is the entry source or package
6368
*/
@@ -105,9 +110,11 @@ public static enum ModuleInfo {
105110
PACKAGE
106111
}
107112

108-
public PZipImporter(LazyPythonClass cls) {
113+
public PZipImporter(LazyPythonClass cls, PDict zipDirectoryCache) {
109114
super(cls);
110115
this.archive = null;
116+
this.prefix = null;
117+
this.moduleZipDirectoryCache = zipDirectoryCache;
111118
if (searchOrder == null) { // define the order once
112119
searchOrder = defineSearchOrder();
113120
}
@@ -121,6 +128,10 @@ private static SearchOrderEntry[] defineSearchOrder() {
121128
};
122129
}
123130

131+
public PDict getZipDirectoryCache() {
132+
return moduleZipDirectoryCache;
133+
}
134+
124135
/**
125136
*
126137
* @return pathname of the Zip archive

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/zipimporter/ZipImporterBuiltins.java

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,17 @@
7878
@CoreFunctions(extendClasses = PythonBuiltinClassType.PZipImporter)
7979
public class ZipImporterBuiltins extends PythonBuiltins {
8080

81-
/**
82-
* cache of the interesting files in the zipfile. exported in ZipimportModuleBuiltins
83-
*/
84-
private static PDict zip_directory_cache;
81+
private static final String INIT_WAS_NOT_CALLED = "zipimporter.__init__() wasn't called";
8582

8683
@Override
8784
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
8885
return ZipImporterBuiltinsFactory.getFactories();
8986
}
9087

91-
public static PDict getCache(PythonObjectFactory factory) {
92-
if (zip_directory_cache == null) {
93-
zip_directory_cache = factory.createDict();
88+
private static void checkInitCalled(PZipImporter self) {
89+
if (self.getPrefix() == null) {
90+
9491
}
95-
return zip_directory_cache;
9692
}
9793

9894
@Builtin(name = __INIT__, fixedNumOfPositionalArgs = 1)
@@ -144,7 +140,7 @@ private void initZipImporter(PZipImporter self, String path) {
144140
if (zipFile == null) {
145141
throw raise(PythonErrorType.ZipImportError, "not a Zip file");
146142
}
147-
Object files = zip_directory_cache.getItem(path);
143+
Object files = self.getZipDirectoryCache().getItem(path);
148144
if (files == null) {
149145
PDict filesDict = factory().createDict();
150146
Enumeration<? extends ZipEntry> entries = zipFile.entries();
@@ -163,7 +159,7 @@ private void initZipImporter(PZipImporter self, String path) {
163159
filesDict.setItem(entry.getName(), tuple);
164160
}
165161
files = filesDict;
166-
zip_directory_cache.setItem(path, files);
162+
self.getZipDirectoryCache().setItem(path, files);
167163
}
168164
self.setArchive(archive);
169165
self.setPrefix(prefix);
@@ -263,7 +259,11 @@ public abstract static class FindModuleNode extends PythonTernaryBuiltinNode {
263259
* @return the zipimporter or none, if the module is not found
264260
*/
265261
@Specialization
266-
public Object doit(PZipImporter self, String fullname, @SuppressWarnings("unused") Object path) {
262+
public Object doit(PZipImporter self, String fullname, @SuppressWarnings("unused") Object path,
263+
@Cached("createBinaryProfile()") ConditionProfile initWasNotCalled) {
264+
if (initWasNotCalled.profile(self.getPrefix() == null)) {
265+
throw raise(PythonErrorType.ValueError, INIT_WAS_NOT_CALLED);
266+
}
267267
return self.findModule(fullname) == null ? PNone.NONE : self;
268268
}
269269

@@ -278,7 +278,11 @@ public abstract static class GetCodeNode extends PythonBinaryBuiltinNode {
278278

279279
@Specialization
280280
public PCode doit(PZipImporter self, String fullname,
281-
@Cached("createBinaryProfile()") ConditionProfile canNotFind) {
281+
@Cached("createBinaryProfile()") ConditionProfile canNotFind,
282+
@Cached("createBinaryProfile()") ConditionProfile initWasNotCalled) {
283+
if (initWasNotCalled.profile(self.getPrefix() == null)) {
284+
throw raise(PythonErrorType.ValueError, INIT_WAS_NOT_CALLED);
285+
}
282286
if (compileNode == null) {
283287
CompilerDirectives.transferToInterpreterAndInvalidate();
284288
compileNode = insert(CompileNode.create());
@@ -304,6 +308,9 @@ public abstract static class GetDataNode extends PythonBinaryBuiltinNode {
304308
@Specialization
305309
@CompilerDirectives.TruffleBoundary
306310
public PBytes doit(PZipImporter self, String pathname) {
311+
if (self.getPrefix() == null) {
312+
throw raise(PythonErrorType.ValueError, INIT_WAS_NOT_CALLED);
313+
}
307314
String archive = self.getArchive();
308315
int len = archive.length();
309316
int index = 0;
@@ -344,7 +351,11 @@ public abstract static class GetFileNameNode extends PythonBinaryBuiltinNode {
344351

345352
@Specialization
346353
public Object doit(PZipImporter self, String fullname,
347-
@Cached("createBinaryProfile()") ConditionProfile canNotFind) {
354+
@Cached("createBinaryProfile()") ConditionProfile canNotFind,
355+
@Cached("createBinaryProfile()") ConditionProfile initWasNotCalled) {
356+
if (initWasNotCalled.profile(self.getPrefix() == null)) {
357+
throw raise(PythonErrorType.ValueError, INIT_WAS_NOT_CALLED);
358+
}
348359
ModuleCodeData moduleCodeData = self.getModuleCode(fullname);
349360
if (canNotFind.profile(moduleCodeData == null)) {
350361
throw raise(PythonErrorType.ZipImportError, " can't find module '%s'", fullname);
@@ -361,7 +372,11 @@ public abstract static class GetSourceNode extends PythonBinaryBuiltinNode {
361372

362373
@Specialization
363374
public String doit(PZipImporter self, String fullname,
364-
@Cached("createBinaryProfile()") ConditionProfile canNotFind) {
375+
@Cached("createBinaryProfile()") ConditionProfile canNotFind,
376+
@Cached("createBinaryProfile()") ConditionProfile initWasNotCalled) {
377+
if (initWasNotCalled.profile(self.getPrefix() == null)) {
378+
throw raise(PythonErrorType.ValueError, INIT_WAS_NOT_CALLED);
379+
}
365380
ModuleCodeData md = self.getModuleCode(fullname);
366381
if (canNotFind.profile(md == null)) {
367382
throw raise(PythonErrorType.ZipImportError, "can't find module '%s'", fullname);
@@ -378,7 +393,11 @@ public abstract static class IsPackageNode extends PythonBinaryBuiltinNode {
378393

379394
@Specialization
380395
public boolean doit(PZipImporter self, String fullname,
381-
@Cached("createBinaryProfile()") ConditionProfile canNotFind) {
396+
@Cached("createBinaryProfile()") ConditionProfile canNotFind,
397+
@Cached("createBinaryProfile()") ConditionProfile initWasNotCalled) {
398+
if (initWasNotCalled.profile(self.getPrefix() == null)) {
399+
throw raise(PythonErrorType.ValueError, INIT_WAS_NOT_CALLED);
400+
}
382401
ModuleInfo moduleInfo = self.getModuleInfo(fullname);
383402
if (canNotFind.profile(moduleInfo == ModuleInfo.NOT_FOUND)) {
384403
throw raise(PythonErrorType.ZipImportError, "can't find module '%s'", fullname);
@@ -396,7 +415,9 @@ public abstract static class LoadModuleNode extends PythonBinaryBuiltinNode {
396415
@Specialization
397416
public Object doit(PZipImporter self, String fullname,
398417
@Cached("create()") GetCodeNode getCodeNode,
399-
@Cached("createBinaryProfile()") ConditionProfile canNotFind) {
418+
@Cached("createBinaryProfile()") ConditionProfile canNotFind,
419+
@Cached("createBinaryProfile()") ConditionProfile initWasNotCalled) {
420+
PCode code = getCodeNode.doit(self, fullname, canNotFind, initWasNotCalled);
400421

401422
PythonModule sysModule = getCore().lookupBuiltinModule("sys");
402423
PDict sysModules = (PDict) sysModule.getAttribute("modules");
@@ -405,7 +426,7 @@ public Object doit(PZipImporter self, String fullname,
405426
module = getCore().factory().createPythonModule(fullname);
406427
sysModules.setItem(fullname, module);
407428
}
408-
PCode code = getCodeNode.doit(self, fullname, canNotFind);
429+
409430
module.setAttribute(SpecialAttributeNames.__LOADER__, self);
410431
module.setAttribute(SpecialAttributeNames.__FILE__, code.getFilename());
411432
if (ModuleInfo.PACKAGE == self.getModuleInfo(fullname)) {

0 commit comments

Comments
 (0)