Add/fix a bunch of sysmodule attributes

This commit is contained in:
Noah committed 2020-08-02 20:59:36 -05:00
1 parent e1656149aa
commit 4bd1153b24
5 files changed
+150 -38

No files matched your search

+16 -3
View File
@@ -64,13 +64,13 @@ fn main() {
return;
}
if let Ok(s) = vm.to_str(&arg) {
println!("{}", s);
eprintln!("{}", s);
}
}
}),
_ => {
if let Ok(r) = vm.to_repr(args.as_object()) {
println!("{}", r);
eprintln!("{}", r);
}
}
}
@@ -158,6 +158,17 @@ fn parse_arguments<'a>(app: App<'a, '_>) -> ArgMatches<'a> {
Arg::with_name("ignore-environment")
.short("E")
.help("Ignore environment variables PYTHON* such as PYTHONPATH"),
)
.arg(
Arg::with_name("isolate")
.short("I")
.help("isolate Python from the user's environment (implies -E and -s)"),
)
.arg(
Arg::with_name("implementation-option")
.short("X")
.takes_value(true)
.help("set implementation-specific option"),
);
#[cfg(feature = "flame-it")]
let app = app
@@ -179,7 +190,8 @@ fn parse_arguments<'a>(app: App<'a, '_>) -> ArgMatches<'a> {
/// Create settings by examining command line arguments and environment
/// variables.
fn create_settings(matches: &ArgMatches) -> PySettings {
let ignore_environment = matches.is_present("ignore-environment");
let ignore_environment =
matches.is_present("ignore-environment") || matches.is_present("isolate");
let mut settings: PySettings = Default::default();
settings.ignore_environment = ignore_environment;
@@ -232,6 +244,7 @@ fn create_settings(matches: &ArgMatches) -> PySettings {
settings.no_site = matches.is_present("no-site");
if matches.is_present("no-user-site")
|| matches.is_present("isolate")
|| (!ignore_environment && env::var_os("PYTHONNOUSERSITE").is_some())
{
settings.no_user_site = true;
+14 -1
View File
@@ -661,6 +661,19 @@ fn key_error_str(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyStringRef {
}
}
fn system_exit_code(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyObjectRef {
match exc.args.read().as_slice().first() {
Some(code) => match_class!(match code {
ref tup @ PyTuple => match tup.as_slice() {
[x] => x.clone(),
_ => code.clone(),
},
other => other.clone(),
}),
None => vm.get_none(),
}
}
pub fn init(ctx: &PyContext) {
let excs = &ctx.exceptions;
@@ -676,7 +689,7 @@ pub fn init(ctx: &PyContext) {
});
extend_class!(ctx, &excs.system_exit, {
"code" => ctx.new_readonly_getset("code", make_arg_getter(0)),
"code" => ctx.new_readonly_getset("code", system_exit_code),
});
extend_class!(ctx, &excs.import_error, {
+1 -1
View File
@@ -45,7 +45,7 @@ pub fn init_importlib(vm: &mut VirtualMachine, initialize_parameter: InitParamet
Ok(())
})();
if zipimport_res.is_err() {
eprintln!("couldn't init zipimport")
warn!("couldn't init zipimport")
}
}
InitParameter::NoInitialize => {
+108 -26
View File
@@ -1,8 +1,10 @@
use num_traits::ToPrimitive;
use std::{env, mem, path};
use crate::frame::FrameRef;
use crate::function::{Args, OptionalArg, PyFuncArgs};
use crate::obj::objstr::PyStringRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult};
use crate::vm::{PySettings, VirtualMachine};
use crate::{builtins, exceptions, py_io, version};
@@ -26,7 +28,11 @@ fn argv(vm: &VirtualMachine) -> PyObjectRef {
fn executable(ctx: &PyContext) -> PyObjectRef {
if let Some(exec_path) = env::args().next() {
if path::Path::new(&exec_path).is_absolute() {
let path = path::Path::new(&exec_path);
if !path.exists() {
return ctx.new_str("");
}
if path.is_absolute() {
return ctx.new_str(exec_path);
}
if let Ok(dir) = env::current_dir() {
@@ -67,50 +73,50 @@ fn getframe(offset: OptionalArg<usize>, vm: &VirtualMachine) -> PyResult<FrameRe
#[derive(Default, Debug)]
struct SysFlags {
/// -d
debug: bool,
debug: u8,
/// -i
inspect: bool,
inspect: u8,
/// -i
interactive: bool,
interactive: u8,
/// -O or -OO
optimize: u8,
/// -B
dont_write_bytecode: bool,
dont_write_bytecode: u8,
/// -s
no_user_site: bool,
no_user_site: u8,
/// -S
no_site: bool,
no_site: u8,
/// -E
ignore_environment: bool,
ignore_environment: u8,
/// -v
verbose: u8,
/// -b
bytes_warning: bool,
bytes_warning: u8,
/// -q
quiet: bool,
quiet: u8,
/// -R
hash_randomization: bool,
hash_randomization: u8,
/// -I
isolated: bool,
isolated: u8,
/// -X dev
dev_mode: bool,
/// -X utf8
utf8_mode: bool,
utf8_mode: u8,
}
impl SysFlags {
fn from_settings(settings: &PySettings) -> Self {
// Start with sensible defaults:
let mut flags: SysFlags = Default::default();
flags.debug = settings.debug;
flags.inspect = settings.inspect;
flags.debug = settings.debug as u8;
flags.inspect = settings.inspect as u8;
flags.optimize = settings.optimize;
flags.no_user_site = settings.no_user_site;
flags.no_site = settings.no_site;
flags.ignore_environment = settings.ignore_environment;
flags.no_user_site = settings.no_user_site as u8;
flags.no_site = settings.no_site as u8;
flags.ignore_environment = settings.ignore_environment as u8;
flags.verbose = settings.verbose;
flags.quiet = settings.quiet;
flags.dont_write_bytecode = settings.dont_write_bytecode;
flags.quiet = settings.quiet as u8;
flags.dont_write_bytecode = settings.dont_write_bytecode as u8;
flags
}
}
@@ -173,7 +179,13 @@ fn sys_getrecursionlimit(vm: &VirtualMachine) -> usize {
vm.recursion_limit.get()
}
fn sys_setrecursionlimit(recursion_limit: usize, vm: &VirtualMachine) -> PyResult {
fn sys_setrecursionlimit(recursion_limit: i32, vm: &VirtualMachine) -> PyResult {
let recursion_limit = recursion_limit
.to_usize()
.filter(|&u| u >= 1)
.ok_or_else(|| {
vm.new_value_error("recursion limit must be greater than or equal to one".to_owned())
})?;
let recursion_depth = vm.frames.borrow().len();
if recursion_limit > recursion_depth + 1 {
@@ -209,7 +221,7 @@ fn sys_git_info(vm: &VirtualMachine) -> PyObjectRef {
}
fn sys_exit(code: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult {
let code = code.unwrap_or_else(|| vm.new_int(0));
let code = code.unwrap_or_else(|| vm.get_none());
Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code]))
}
@@ -350,7 +362,6 @@ pub fn sysconfigdata_name() -> String {
}
#[pystruct_sequence(module = "sys", name = "hash_info")]
#[derive(Debug)]
struct PyHashInfo {
width: usize,
modulus: PyUHash,
@@ -360,9 +371,10 @@ struct PyHashInfo {
algorithm: &'static str,
hash_bits: usize,
seed_bits: usize,
cutoff: usize,
}
impl PyHashInfo {
pub const INFO: Self = {
const INFO: Self = {
use rustpython_common::hash::*;
PyHashInfo {
width: BITS,
@@ -373,20 +385,73 @@ impl PyHashInfo {
algorithm: ALGO,
hash_bits: HASH_BITS,
seed_bits: SEED_BITS,
cutoff: 0, // no small string optimizations
}
};
}
#[pystruct_sequence(module = "sys", name = "float_info")]
struct PyFloatInfo {
max: f64,
max_exp: i32,
max_10_exp: i32,
min: f64,
min_exp: i32,
min_10_exp: i32,
dig: u32,
mant_dig: u32,
epsilon: f64,
radix: u32,
rounds: i32,
}
impl PyFloatInfo {
const INFO: Self = PyFloatInfo {
max: f64::MAX,
max_exp: f64::MAX_EXP,
max_10_exp: f64::MAX_10_EXP,
min: f64::MIN,
min_exp: f64::MIN_EXP,
min_10_exp: f64::MIN_10_EXP,
dig: f64::DIGITS,
mant_dig: f64::MANTISSA_DIGITS,
epsilon: f64::EPSILON,
radix: f64::RADIX,
rounds: 1, // FE_TONEAREST
};
}
#[pystruct_sequence(module = "sys", name = "int_info")]
struct PyIntInfo {
bits_per_digit: usize,
sizeof_digit: usize,
}
impl PyIntInfo {
const INFO: Self = PyIntInfo {
bits_per_digit: 30, //?
sizeof_digit: std::mem::size_of::<u32>(),
};
}
pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectRef) {
let ctx = &vm.ctx;
let flags_type = SysFlags::make_class(ctx);
extend_class!(ctx, flags_type, {
(slot new) => |_cls: PyClassRef, _args: PyFuncArgs, vm: &VirtualMachine| -> PyResult {
Err(vm.new_type_error("cannot create 'sys.flags' instances".to_owned()))
},
});
let flags = SysFlags::from_settings(&vm.state.settings)
.into_struct_sequence(vm, flags_type)
.unwrap();
let version_info_type = version::VersionInfo::make_class(ctx);
let version_info = version::get_version_info()
extend_class!(ctx, version_info_type, {
(slot new) => |_cls: PyClassRef, _args: PyFuncArgs, vm: &VirtualMachine| -> PyResult {
Err(vm.new_type_error("cannot create 'sys.version_info' instances".to_owned()))
},
});
let version_info = version::VersionInfo::VERSION
.into_struct_sequence(vm, version_info_type)
.unwrap();
@@ -395,11 +460,23 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR
.into_struct_sequence(vm, hash_info_type)
.unwrap();
let float_info_type = PyFloatInfo::make_class(ctx);
let float_info = PyFloatInfo::INFO
.into_struct_sequence(vm, float_info_type)
.unwrap();
let int_info_type = PyIntInfo::make_class(ctx);
let int_info = PyIntInfo::INFO
.into_struct_sequence(vm, int_info_type)
.unwrap();
// TODO Add crate version to this namespace
let implementation = py_namespace!(vm, {
"name" => ctx.new_str("rustpython".to_owned()),
"cache_tag" => ctx.new_str("rustpython-01".to_owned()),
"_multiarch" => ctx.new_str(MULTIARCH.to_owned()),
"version" => version_info.clone(),
"hexversion" => ctx.new_int(version::VERSION_HEX),
});
let path = ctx.new_list(
@@ -532,7 +609,7 @@ settrace() -- set the global debug tracing function
"gettrace" => ctx.new_function(sys_gettrace),
"hash_info" => hash_info,
"intern" => ctx.new_function(sys_intern),
"maxunicode" => ctx.new_int(0x0010_FFFF),
"maxunicode" => ctx.new_int(std::char::MAX as u32),
"maxsize" => ctx.new_int(std::isize::MAX),
"path" => path,
"ps1" => ctx.new_str(">>>>> ".to_owned()),
@@ -566,6 +643,11 @@ settrace() -- set the global debug tracing function
"__displayhook__" => ctx.new_function(sys_displayhook),
"excepthook" => ctx.new_function(sys_excepthook),
"__excepthook__" => ctx.new_function(sys_excepthook),
"hexversion" => ctx.new_int(version::VERSION_HEX),
"api_version" => ctx.new_int(0x0), // what C api?
"float_info" => float_info,
"int_info" => int_info,
"float_repr_style" => ctx.new_str("short".to_owned()),
});
#[cfg(windows)]
+11 -7
View File
@@ -1,12 +1,20 @@
/* Several function to retrieve version information.
*/
use chrono::prelude::DateTime;
use chrono::Local;
use std::time::{Duration, UNIX_EPOCH};
const MAJOR: usize = 3;
const MINOR: usize = 5;
const MICRO: usize = 0;
const RELEASELEVEL: &str = "alpha";
const RELEASELEVEL_N: usize = 0xA;
const SERIAL: usize = 0;
pub const VERSION_HEX: usize =
(MAJOR << 24) | (MINOR << 16) | (MICRO << 8) | (RELEASELEVEL_N << 4) | SERIAL;
#[pystruct_sequence(module = "sys", name = "version_info")]
#[derive(Default, Debug)]
pub struct VersionInfo {
@@ -16,10 +24,6 @@ pub struct VersionInfo {
releaselevel: &'static str,
serial: usize,
}
extern crate chrono;
use chrono::prelude::DateTime;
use chrono::Local;
use std::time::{Duration, UNIX_EPOCH};
pub fn get_version() -> String {
format!(
@@ -30,14 +34,14 @@ pub fn get_version() -> String {
)
}
pub fn get_version_info() -> VersionInfo {
VersionInfo {
impl VersionInfo {
pub const VERSION: VersionInfo = VersionInfo {
major: MAJOR,
minor: MINOR,
micro: MICRO,
releaselevel: RELEASELEVEL,
serial: SERIAL,
}
};
}
pub fn get_version_number() -> String {