com.oracle.graal.python.runtime.PythonOptions Maven / Gradle / Ivy
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates.
* Copyright (c) 2013, Regents of the University of California
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.oracle.graal.python.runtime;
import static com.oracle.graal.python.builtins.modules.SysModuleBuiltins.INT_MAX_STR_DIGITS_THRESHOLD;
import static com.oracle.graal.python.nodes.StringLiterals.T_DEFAULT;
import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
import static com.oracle.graal.python.nodes.StringLiterals.T_JAVA;
import static com.oracle.graal.python.nodes.StringLiterals.T_SPACE;
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.graalvm.options.OptionCategory;
import org.graalvm.options.OptionDescriptor;
import org.graalvm.options.OptionDescriptors;
import org.graalvm.options.OptionKey;
import org.graalvm.options.OptionStability;
import org.graalvm.options.OptionType;
import org.graalvm.options.OptionValues;
import com.oracle.graal.python.PythonLanguage;
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
import com.oracle.graal.python.builtins.objects.str.StringUtils;
import com.oracle.graal.python.util.PythonUtils;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Option;
import com.oracle.truffle.api.TruffleLanguage.Env;
import com.oracle.truffle.api.dsl.Idempotent;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.strings.TruffleString;
/**
* The options for Python. Note that some options have an effect on the AST structure, and thus must
* be the same for all contexts in an engine. We annotate these with {@link EngineOption} and the
* PythonLanguage will ensure that these are matched across contexts.
*/
@Option.Group(PythonLanguage.ID)
public final class PythonOptions {
private static final String J_STRING_LIST_SEPARATOR = "🏆";
private static final TruffleString T_STRING_LIST_SEPARATOR = tsLiteral(J_STRING_LIST_SEPARATOR);
/**
* Whether Java classes are included that implement the SSL module. These come from packages
* including (but not limited to): javax.net.ssl, org.bouncycastle, java.security, javax.crypto,
* sun.security
*/
public static final boolean WITHOUT_SSL = Boolean.getBoolean("python.WithoutSSL");
/**
* Whether cryptographic hashing functions are implemented via java.security.MessageDigest,
* javax.crypto.Mac and related functions.
*/
public static final boolean WITHOUT_DIGEST = Boolean.getBoolean("python.WithoutDigest");
/**
* Whether Java classes are included that relate to Unix-specific access, modify process
* properties such as the default timezone, access the platform's Runtime MXBean, or spawn
* subprocesses are available.
*/
public static final boolean WITHOUT_PLATFORM_ACCESS = Boolean.getBoolean("python.WithoutPlatformAccess");
/**
* This property can be used to exclude zip, zlib, lzma, and bzip2 support from the Python core.
*/
public static final boolean WITHOUT_COMPRESSION_LIBRARIES = Boolean.getBoolean("python.WithoutCompressionLibraries");
/**
* This property can be used to exclude native posix support from the build. Only Java emulation
* will be available.
*/
public static final boolean WITHOUT_NATIVE_POSIX = Boolean.getBoolean("python.WithoutNativePosix");
/**
* This property can be used to exclude socket and inet support from the Java posix backend.
*/
public static final boolean WITHOUT_JAVA_INET = Boolean.getBoolean("python.WithoutJavaInet");
/**
* This property can be used to control if async actions are automatically scheduled using
* daemon threads or via embedder calling a polling API on the main thread.
*/
public static final boolean AUTOMATIC_ASYNC_ACTIONS = !"false".equalsIgnoreCase(System.getProperty("python.AutomaticAsyncActions"));
public enum HPyBackendMode {
NFI,
JNI,
LLVM
}
static final OptionType HPY_BACKEND_TYPE = new OptionType<>("HPyBackend", s -> {
try {
return HPyBackendMode.valueOf(s.toUpperCase());
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Backend can be one of: " + Arrays.toString(HPyBackendMode.values()));
}
});
private static final OptionType TS_OPTION_TYPE = new OptionType<>("graal.python.TruffleString", PythonUtils::toTruffleStringUncached);
private PythonOptions() {
// no instances
}
@Option(category = OptionCategory.EXPERT, help = "Set the home of Python. Equivalent of GRAAL_PYTHONHOME env variable. " +
"Determines default values for the CoreHome, StdLibHome, SysBasePrefix, SysPrefix.", usageSyntax = "", stability = OptionStability.STABLE) //
public static final OptionKey PythonHome = new OptionKey<>("");
@Option(category = OptionCategory.USER, help = "Set the location of sys.prefix. Overrides any environment variables or Java options.", usageSyntax = "", stability = OptionStability.STABLE) //
public static final OptionKey SysPrefix = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@Option(category = OptionCategory.EXPERT, help = "Set the location of sys.base_prefix. Overrides any environment variables or Java options.", usageSyntax = "", stability = OptionStability.STABLE) //
public static final OptionKey SysBasePrefix = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@Option(category = OptionCategory.USER, help = "Set the location of lib/graalpy" + PythonLanguage.GRAALVM_MAJOR + "." + //
PythonLanguage.GRAALVM_MINOR + ". Overrides any environment variables or Java options.", //
usageSyntax = "", stability = OptionStability.STABLE) //
public static final OptionKey CoreHome = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@Option(category = OptionCategory.USER, help = "Set the location of lib/python" + PythonLanguage.MAJOR + "." + PythonLanguage.MINOR +
". Overrides any environment variables or Java options.", usageSyntax = "", stability = OptionStability.STABLE) //
public static final OptionKey StdLibHome = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -i flag. Inspect interactively after running a script.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey InspectFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -q flag. Don't print version and copyright messages on interactive startup.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey QuietFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -S flag. Don't imply 'import site' on initialization.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey NoSiteFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -s flag. Don't add user site directory to sys.path.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey NoUserSiteFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -E flag. Ignore PYTHON* environment variables.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey IgnoreEnvironmentFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to setting the PYTHONPATH environment variable for the standard launcher. ':'-separated list of directories prefixed to the default module search path.", usageSyntax = "[:]", stability = OptionStability.STABLE) //
public static final OptionKey PythonPath = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@EngineOption @Option(category = OptionCategory.USER, help = "Equivalent to setting the PYTHONIOENCODING environment variable for the standard launcher.", usageSyntax = "[:]", stability = OptionStability.STABLE) //
public static final OptionKey StandardStreamEncoding = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@Option(category = OptionCategory.USER, help = "Remove assert statements and any code conditional on the value of __debug__.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey PythonOptimizeFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -v flag. Turn on verbose mode.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey VerboseFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -u flag. Force stdout and stderr to be unbuffered.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey UnbufferedIO = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -I flag. Isolate from the users environment by not adding the cwd to the path", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey IsolateFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -X warn_default_encoding flag. Enable opt-in EncodingWarning for 'encoding=None'", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey WarnDefaultEncodingFlag = new OptionKey<>(false);
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -X int_max_str_digits option.", stability = OptionStability.STABLE) //
public static final OptionKey IntMaxStrDigits = new OptionKey<>(SysModuleBuiltins.INT_DEFAULT_MAX_STR_DIGITS,
new OptionType<>("IntMaxStrDigits", (input) -> {
try {
int value = Integer.parseInt(input);
if (value == 0 || value >= INT_MAX_STR_DIGITS_THRESHOLD) {
return value;
}
} catch (NumberFormatException e) {
// fallthrough
}
throw new IllegalArgumentException(String.format("IntMaxStrDigits: invalid limit; must be >= %d or 0 for unlimited.", INT_MAX_STR_DIGITS_THRESHOLD));
}));
@Option(category = OptionCategory.USER, help = "Equivalent to the Python -B flag. Don't write bytecode files.", usageSyntax = "true|false", stability = OptionStability.STABLE) //
public static final OptionKey DontWriteBytecodeFlag = new OptionKey<>(true);
@Option(category = OptionCategory.USER, help = "If this is set, GraalPython will write .pyc files in a mirror directory tree at this path, " +
"instead of in __pycache__ directories within the source tree. " +
"Equivalent to setting the PYTHONPYCACHEPREFIX environment variable for the standard launcher.", usageSyntax = "", stability = OptionStability.STABLE) //
public static final OptionKey PyCachePrefix = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@Option(category = OptionCategory.USER, help = "Equivalent to setting the PYTHONWARNINGS environment variable for the standard launcher.", //
usageSyntax = "[:[:[:[:]]]][,[:[:[:[:]]]]]", stability = OptionStability.STABLE) //
public static final OptionKey WarnOptions = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@Option(category = OptionCategory.USER, help = "Equivalent to setting PYTHONHASHSEED environment variable", usageSyntax = "random|[0,4294967295]", stability = OptionStability.STABLE) //
public static final OptionKey> HashSeed = new OptionKey<>(Optional.empty(),
new OptionType<>("HashSeed", input -> {
if ("random".equals(input)) {
return Optional.empty();
}
try {
return Optional.of(Integer.parseUnsignedInt(input));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("PYTHONHASHSEED must be \"random\" or an integer in range [0; 4294967295]");
}
}));
@EngineOption @Option(category = OptionCategory.USER, help = "Choose the backend for the POSIX module.", usageSyntax = "java|native|llvm", stability = OptionStability.STABLE) //
public static final OptionKey PosixModuleBackend = new OptionKey<>(T_JAVA, TS_OPTION_TYPE);
@Option(category = OptionCategory.USER, help = "Value of the --check-hash-based-pycs command line option" +
"- 'default' means the 'check_source' flag in hash-based pycs" +
" determines invalidation" +
"- 'always' causes the interpreter to hash the source file for" +
" invalidation regardless of value of 'check_source' bit" +
"- 'never' causes the interpreter to always assume hash-based pycs are" +
" valid" +
"The default value is 'default'." +
"See PEP 552 'Deterministic pycs' for more details.", usageSyntax = "default|always|never", stability = OptionStability.STABLE) //
public static final OptionKey CheckHashPycsMode = new OptionKey<>(T_DEFAULT, TS_OPTION_TYPE);
@Option(category = OptionCategory.INTERNAL, help = "Set the location of C API home. Overrides any environment variables or Java options.", usageSyntax = "", stability = OptionStability.STABLE) //
public static final OptionKey CAPI = new OptionKey<>(T_EMPTY_STRING, TS_OPTION_TYPE);
@EngineOption @Option(category = OptionCategory.INTERNAL, help = "Expose internal sources as normal sources, so they will show up in the debugger and stacks", usageSyntax = "true|false") //
public static final OptionKey ExposeInternalSources = new OptionKey<>(false);
@EngineOption @Option(category = OptionCategory.INTERNAL, help = "Eagerly initialize source sections.", usageSyntax = "true|false") //
public static final OptionKey ForceInitializeSourceSections = new OptionKey<>(false);
@EngineOption @Option(category = OptionCategory.INTERNAL, help = "Print the java stacktrace. Possible modes:" +
" 1 Print Java stacktrace for Java exceptions only." +
" 2 Print Java stacktrace for Python exceptions only (ATTENTION: this will have a notable performance impact)." +
" 3 Combines 1 and 2.", usageSyntax = "1|2|3") //
public static final OptionKey WithJavaStacktrace = new OptionKey<>(0);
@Option(category = OptionCategory.INTERNAL, usageSyntax = "true|false", help = "") //
public static final OptionKey CatchGraalPythonExceptionForUnitTesting = new OptionKey<>(false);
@EngineOption @Option(category = OptionCategory.INTERNAL, usageSyntax = "true|false", help = "Enable catching all Exceptions in generic try-catch statements.") //
public static final OptionKey CatchAllExceptions = new OptionKey<>(false);
@EngineOption @Option(category = OptionCategory.INTERNAL, help = "Choose the backend for HPy binary mode.", usageSyntax = "jni|nfi|llvm", stability = OptionStability.EXPERIMENTAL) //
public static final OptionKey HPyBackend = new OptionKey<>(HPyBackendMode.JNI, HPY_BACKEND_TYPE);
@EngineOption @Option(category = OptionCategory.INTERNAL, usageSyntax = "true|false", help = "If {@code true}, code is enabled that tries to reduce expensive upcalls into the runtime" +
"when HPy API functions are used. This is achieved by mirroring data in native memory.", stability = OptionStability.EXPERIMENTAL) //
public static final OptionKey HPyEnableJNIFastPaths = new OptionKey<>(true);
@EngineOption @Option(category = OptionCategory.INTERNAL, usageSyntax = "
© 2015 - 2024 Weber Informatics LLC | Privacy Policy