Skip to content

Commit e565898

Browse files
committed
make test_bz2 pass and fast
1 parent 32eff74 commit e565898

File tree

19 files changed

+2085
-15
lines changed

19 files changed

+2085
-15
lines changed

graalpython/com.oracle.graal.python.cext/bz2/bz2.c

Lines changed: 578 additions & 0 deletions
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python.cext/setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,10 @@ def build(capi_home):
473473
subdir="zlib",
474474
libname="libzsupport",
475475
libs=['z'])
476+
build_nativelibsupport(capi_home,
477+
subdir="bz2",
478+
libname="libbz2support",
479+
deps=[Bzip2Depedency("bz2", "bzip2==1.0.8", "BZIP2")])
476480
build_libpython(capi_home)
477481
build_builtin_exts(capi_home)
478482
finally:

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_bz2.txt

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,93 @@
44
*graalpython.lib-python.3.test.test_bz2.BZ2CompressorTest.testCompressEmptyString
55
*graalpython.lib-python.3.test.test_bz2.BZ2CompressorTest.testPickle
66
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.testDecompress
7+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.testDecompress4G
8+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.testDecompressChunks10
9+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.testDecompressUnusedData
10+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.testDecompressorChunksMaxsize
11+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.testEOFError
12+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.testPickle
13+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.test_Constructor
14+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.test_decompressor_inputbuf_1
15+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.test_decompressor_inputbuf_2
16+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.test_decompressor_inputbuf_3
17+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.test_failure
18+
*graalpython.lib-python.3.test.test_bz2.BZ2DecompressorTest.test_refleaks_in___init__
19+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testAppend
20+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testBadArgs
21+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testClosedIteratorDeadlock
22+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testContextProtocol
23+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testDecompressLimited
24+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testFileno
25+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testIterator
26+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testIteratorMultiStream
27+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testMixedIterationAndReads
28+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testMultiStreamOrdering
29+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testOpenBytesFilename
30+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testOpenDel
31+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testOpenNonexistent
32+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testOpenPathLikeFilename
33+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testPeek
34+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testPeekBytesIO
35+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testRead
36+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testRead0
37+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testRead100
38+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadBadFile
39+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadBytesIO
40+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadChunk10
41+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadChunk10MultiStream
42+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadInto
43+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadLine
44+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadLineMultiStream
45+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadLines
46+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadLinesMultiStream
47+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadMonkeyMultiStream
48+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadMultiStream
49+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadMultiStreamTrailingJunk
50+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadTrailingJunk
51+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadable
52+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testReadlinesNoNewline
53+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekBackwards
54+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekBackwardsAcrossStreams
55+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekBackwardsBytesIO
56+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekBackwardsFromEnd
57+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekBackwardsFromEndAcrossStreams
58+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekForward
59+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekForwardAcrossStreams
60+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekForwardBytesIO
61+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekPostEnd
62+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekPostEndMultiStream
63+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekPostEndTwice
64+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekPostEndTwiceMultiStream
65+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekPreStart
66+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekPreStartMultiStream
67+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testSeekable
68+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testThreading
69+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testWritable
70+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testWrite
71+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testWriteBytesIO
72+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testWriteChunks10
73+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testWriteLines
74+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testWriteMethodsOnReadOnlyFile
75+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.testWriteNonDefaultCompressLevel
76+
*graalpython.lib-python.3.test.test_bz2.BZ2FileTest.test_read_truncated
77+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testCompress
78+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testCompressEmptyString
79+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testDecompress
80+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testDecompressBadData
81+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testDecompressEmpty
82+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testDecompressIncomplete
83+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testDecompressMultiStream
84+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testDecompressMultiStreamTrailingJunk
85+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testDecompressToEmptyString
86+
*graalpython.lib-python.3.test.test_bz2.CompressDecompressTest.testDecompressTrailingJunk
87+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_bad_params
88+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_binary_modes
89+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_encoding
90+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_encoding_error_handler
91+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_fileobj
92+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_implicit_binary_modes
93+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_newline
94+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_text_modes
95+
*graalpython.lib-python.3.test.test_bz2.OpenTest.test_x_mode
96+
*graalpython.lib-python.3.test.test_bz2.TestMain.test_main

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ protected boolean patchContext(PythonContext context, Env newEnv) {
234234
protected PythonContext createContext(Env env) {
235235
assert this.isWithThread == null || this.isWithThread == PythonOptions.isWithThread(env) : "conflicting thread options in the same language!";
236236
this.isWithThread = PythonOptions.isWithThread(env);
237-
Python3Core newCore = new Python3Core(new PythonParserImpl(env));
237+
Python3Core newCore = new Python3Core(new PythonParserImpl(env), env.isNativeAccessAllowed());
238238
final PythonContext context = new PythonContext(this, env, newCore);
239239
context.initializeHomeAndPrefixPaths(env, getLanguageHome());
240240

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@
102102
import com.oracle.graal.python.builtins.modules.WeakRefModuleBuiltins;
103103
import com.oracle.graal.python.builtins.modules.ZipImportModuleBuiltins;
104104
import com.oracle.graal.python.builtins.objects.NotImplementedBuiltins;
105+
import com.oracle.graal.python.builtins.modules.bz2.BZ2CompressorBuiltins;
106+
import com.oracle.graal.python.builtins.modules.bz2.BZ2DecompressorBuiltins;
107+
import com.oracle.graal.python.builtins.modules.bz2.BZ2ModuleBuiltins;
105108
import com.oracle.graal.python.builtins.modules.io.BufferedReaderBuiltins;
106109
import com.oracle.graal.python.builtins.modules.io.IOModuleBuiltins;
107110
import com.oracle.graal.python.builtins.modules.zlib.ZLibModuleBuiltins;
@@ -310,7 +313,7 @@ private static String[] initializeCoreFiles() {
310313
c = null;
311314
}
312315

313-
private static PythonBuiltins[] initializeBuiltins() {
316+
private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed) {
314317
List<PythonBuiltins> builtins = new ArrayList<>(Arrays.asList(
315318
new BuiltinConstructors(),
316319
new BuiltinFunctions(),
@@ -442,6 +445,11 @@ private static PythonBuiltins[] initializeBuiltins() {
442445
builtins.add(new LsprofModuleBuiltins());
443446
builtins.add(LsprofModuleBuiltins.newProfilerBuiltins());
444447
}
448+
if (nativeAccessAllowed) {
449+
builtins.add(new BZ2CompressorBuiltins());
450+
builtins.add(new BZ2DecompressorBuiltins());
451+
builtins.add(new BZ2ModuleBuiltins());
452+
}
445453
if (!ImageInfo.inImageRuntimeCode()) {
446454
ServiceLoader<PythonBuiltins> providers = ServiceLoader.load(PythonBuiltins.class, Python3Core.class.getClassLoader());
447455
for (PythonBuiltins builtin : providers) {
@@ -473,9 +481,9 @@ private static PythonBuiltins[] initializeBuiltins() {
473481

474482
private final PythonObjectFactory objectFactory = PythonObjectFactory.getUncached();
475483

476-
public Python3Core(PythonParser parser) {
484+
public Python3Core(PythonParser parser, boolean isNativeSupportAllowed) {
477485
this.parser = parser;
478-
this.builtins = initializeBuiltins();
486+
this.builtins = initializeBuiltins(isNativeSupportAllowed);
479487
this.coreFiles = initializeCoreFiles();
480488
}
481489

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ public enum PythonBuiltinClassType implements TruffleObject {
138138
PLZMADecompressor("LZMADecompressor", "_lzma"),
139139
LsprofProfiler("Profiler", "_lsprof"),
140140
PStruct("Struct", "_struct"),
141+
BZ2Compressor("BZ2Compressor", "_bz2"),
142+
BZ2Decompressor("BZ2Decompressor", "_bz2"),
141143
ZlibCompress("Compress", "zlib"),
142144
ZlibDecompress("Decompress", "zlib"),
143145
PBufferedReader("BufferedReader", "_io"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.builtins.modules.bz2;
42+
43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.BZ2Compressor;
44+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
45+
import static com.oracle.graal.python.builtins.modules.bz2.Bz2Nodes.BZ_OK;
46+
import static com.oracle.graal.python.builtins.modules.bz2.Bz2Nodes.errorHandling;
47+
import static com.oracle.graal.python.nodes.ErrorMessages.COMPRESSLEVEL_MUST_BE_BETWEEN_1_AND_9;
48+
import static com.oracle.graal.python.nodes.ErrorMessages.COMPRESSOR_HAS_BEEN_FLUSHED;
49+
import static com.oracle.graal.python.nodes.ErrorMessages.REPEATED_CALL_TO_FLUSH;
50+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INIT__;
51+
52+
import java.util.List;
53+
54+
import com.oracle.graal.python.PythonLanguage;
55+
import com.oracle.graal.python.annotations.ArgumentClinic;
56+
import com.oracle.graal.python.builtins.Builtin;
57+
import com.oracle.graal.python.builtins.CoreFunctions;
58+
import com.oracle.graal.python.builtins.PythonBuiltins;
59+
import com.oracle.graal.python.builtins.objects.PNone;
60+
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
61+
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
62+
import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
63+
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
64+
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
65+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
66+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
67+
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
68+
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
69+
import com.oracle.graal.python.runtime.NFIBz2Support;
70+
import com.oracle.graal.python.runtime.NativeLibrary;
71+
import com.oracle.graal.python.runtime.PythonContext;
72+
import com.oracle.truffle.api.dsl.Cached;
73+
import com.oracle.truffle.api.dsl.Cached.Shared;
74+
import com.oracle.truffle.api.dsl.CachedContext;
75+
import com.oracle.truffle.api.dsl.Fallback;
76+
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
77+
import com.oracle.truffle.api.dsl.NodeFactory;
78+
import com.oracle.truffle.api.dsl.Specialization;
79+
import com.oracle.truffle.api.profiles.ConditionProfile;
80+
81+
@CoreFunctions(extendClasses = BZ2Compressor)
82+
public class BZ2CompressorBuiltins extends PythonBuiltins {
83+
@Override
84+
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
85+
return BZ2CompressorBuiltinsFactory.getFactories();
86+
}
87+
88+
@Builtin(name = __INIT__, minNumOfPositionalArgs = 1, parameterNames = {"$self", "compresslevel"})
89+
@ArgumentClinic(name = "compresslevel", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "9", useDefaultForNone = true)
90+
@GenerateNodeFactory
91+
public abstract static class InitNode extends PythonBinaryClinicBuiltinNode {
92+
93+
@Override
94+
protected ArgumentClinicProvider getArgumentClinic() {
95+
return BZ2CompressorBuiltinsClinicProviders.InitNodeClinicProviderGen.INSTANCE;
96+
}
97+
98+
@Specialization(guards = {"compresslevel >= 1", "compresslevel <= 9"})
99+
PNone init(BZ2Object.BZ2Compressor self, int compresslevel,
100+
@CachedContext(PythonLanguage.class) PythonContext ctxt,
101+
@Cached NativeLibrary.InvokeNativeFunction createStream,
102+
@Cached NativeLibrary.InvokeNativeFunction compressInit,
103+
@Cached ConditionProfile errProfile) {
104+
NFIBz2Support bz2Support = ctxt.getNFIBz2Support();
105+
Object bzst = bz2Support.createStream(createStream);
106+
int err = bz2Support.compressInit(bzst, compresslevel, compressInit);
107+
if (errProfile.profile(err != BZ_OK)) {
108+
errorHandling(err, getRaiseNode());
109+
}
110+
self.init(bzst, bz2Support);
111+
return PNone.NONE;
112+
}
113+
114+
@SuppressWarnings("unused")
115+
@Fallback
116+
Object err(Object self, Object compresslevel) {
117+
throw raise(ValueError, COMPRESSLEVEL_MUST_BE_BETWEEN_1_AND_9);
118+
}
119+
}
120+
121+
@Builtin(name = "compress", minNumOfPositionalArgs = 2, parameterNames = {"$self", "$data"})
122+
@GenerateNodeFactory
123+
abstract static class CompressNode extends PythonBinaryBuiltinNode {
124+
125+
@Specialization(guards = {"!self.isFlushed()"})
126+
PBytes doNativeBytes(BZ2Object.BZ2Compressor self, PBytesLike data,
127+
@Shared("c") @CachedContext(PythonLanguage.class) PythonContext ctxt,
128+
@Cached SequenceStorageNodes.GetInternalByteArrayNode toBytes,
129+
@Cached SequenceStorageNodes.LenNode lenNode,
130+
@Shared("c") @Cached Bz2Nodes.Bz2NativeCompress compress) {
131+
synchronized (self) {
132+
byte[] bytes = toBytes.execute(data.getSequenceStorage());
133+
int len = lenNode.execute(data.getSequenceStorage());
134+
return factory().createBytes(compress.compress(self, ctxt, bytes, len));
135+
}
136+
}
137+
138+
@Specialization(guards = {"!self.isFlushed()"})
139+
PBytes doNativeObject(BZ2Object.BZ2Compressor self, Object data,
140+
@Shared("c") @CachedContext(PythonLanguage.class) PythonContext ctxt,
141+
@Cached BytesNodes.ToBytesNode toBytes,
142+
@Shared("c") @Cached Bz2Nodes.Bz2NativeCompress compress) {
143+
synchronized (self) {
144+
byte[] bytes = toBytes.execute(data);
145+
int len = bytes.length;
146+
return factory().createBytes(compress.compress(self, ctxt, bytes, len));
147+
}
148+
}
149+
150+
@SuppressWarnings("unused")
151+
@Specialization(guards = "self.isFlushed()")
152+
PNone error(BZ2Object.BZ2Compressor self, Object data) {
153+
throw raise(ValueError, COMPRESSOR_HAS_BEEN_FLUSHED);
154+
}
155+
}
156+
157+
@Builtin(name = "flush", minNumOfPositionalArgs = 1, parameterNames = {"$self"})
158+
@GenerateNodeFactory
159+
abstract static class FlushNode extends PythonUnaryBuiltinNode {
160+
161+
@Specialization(guards = {"!self.isFlushed()"})
162+
PBytes doit(BZ2Object.BZ2Compressor self,
163+
@CachedContext(PythonLanguage.class) PythonContext ctxt,
164+
@Cached Bz2Nodes.Bz2NativeCompress compress) {
165+
synchronized (self) {
166+
self.setFlushed();
167+
return factory().createBytes(compress.flush(self, ctxt));
168+
}
169+
}
170+
171+
@SuppressWarnings("unused")
172+
@Specialization(guards = "self.isFlushed()")
173+
PNone error(BZ2Object.BZ2Compressor self) {
174+
throw raise(ValueError, REPEATED_CALL_TO_FLUSH);
175+
}
176+
}
177+
}

0 commit comments

Comments
 (0)