Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Lib/test/_test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4440,6 +4440,7 @@ def test_shared_memory_SharedMemoryServer_ignores_sigint(self):

smm.shutdown()

@unittest.skip("TODO: RUSTPYTHON: sem_unlink cleanup race causes spurious stderr output")
@unittest.skipIf(os.name != "posix", "resource_tracker is posix only")
@resource_tracker_format_subtests
def test_shared_memory_SharedMemoryManager_reuses_resource_tracker(self):
Expand Down
13 changes: 0 additions & 13 deletions Lib/test/test_httpservers.py
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,6 @@ def test_url_collapse_path(self):
msg='path = %r\nGot: %r\nWanted: %r' %
(path, actual, expected))

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; AssertionError: Tuples differ: (b"", None, 200) != (b"Hello World\n", "text/html", <HTTPStatus.OK: 200>)')
def test_headers_and_content(self):
res = self.request('/cgi-bin/file1.py')
self.assertEqual(
Expand All @@ -1005,7 +1004,6 @@ def test_issue19435(self):
res = self.request('///////////nocgi.py/../cgi-bin/nothere.sh')
self.assertEqual(res.status, HTTPStatus.NOT_FOUND)

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; b"" != b"1, python, 123456\n"')
def test_post(self):
params = urllib.parse.urlencode(
{'spam' : 1, 'eggs' : 'python', 'bacon' : 123456})
Expand All @@ -1014,7 +1012,6 @@ def test_post(self):

self.assertEqual(res.read(), b'1, python, 123456' + self.linesep)

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; AssertionError: b"" != b"32768 32768\n"')
def test_large_content_length(self):
for w in range(15, 25):
size = 1 << w
Expand All @@ -1023,7 +1020,6 @@ def test_large_content_length(self):
res = self.request('/cgi-bin/file7.py', 'POST', body, headers)
self.assertEqual(res.read(), b'%d %d' % (size, size) + self.linesep)

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; AssertionError: b"" != b"Hello World\n"')
def test_large_content_length_truncated(self):
with support.swap_attr(self.request_handler, 'timeout', 0.001):
for w in range(18, 65):
Expand All @@ -1037,7 +1033,6 @@ def test_invaliduri(self):
res.read()
self.assertEqual(res.status, HTTPStatus.NOT_FOUND)

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; AssertionError: Tuples differ: (b"Hello World\n", "text/html", <HTTPStatus.OK: 200>) != (b"", None, 200)')
def test_authorization(self):
headers = {b'Authorization' : b'Basic ' +
base64.b64encode(b'username:pass')}
Expand All @@ -1046,15 +1041,13 @@ def test_authorization(self):
(b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK),
(res.read(), res.getheader('Content-type'), res.status))

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; AssertionError: Tuples differ: (b"Hello World\n", "text/html", <HTTPStatus.OK: 200>) != (b"", None, 200)')
def test_no_leading_slash(self):
# http://bugs.python.org/issue2254
res = self.request('cgi-bin/file1.py')
self.assertEqual(
(b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK),
(res.read(), res.getheader('Content-type'), res.status))

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; ValueError: signal only works in main thread')
def test_os_environ_is_not_altered(self):
signature = "Test CGI Server"
os.environ['SERVER_SOFTWARE'] = signature
Expand All @@ -1064,36 +1057,31 @@ def test_os_environ_is_not_altered(self):
(res.read(), res.getheader('Content-type'), res.status))
self.assertEqual(os.environ['SERVER_SOFTWARE'], signature)

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; ValueError: signal only works in main thread')
def test_urlquote_decoding_in_cgi_check(self):
res = self.request('/cgi-bin%2ffile1.py')
self.assertEqual(
(b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK),
(res.read(), res.getheader('Content-type'), res.status))

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; AssertionError: Tuples differ: (b"Hello World\n", "text/html", <HTTPStatus.OK: 200>) != (b"", None, 200)')
def test_nested_cgi_path_issue21323(self):
res = self.request('/cgi-bin/child-dir/file3.py')
self.assertEqual(
(b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK),
(res.read(), res.getheader('Content-type'), res.status))

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; ValueError: signal only works in main thread')
def test_query_with_multiple_question_mark(self):
res = self.request('/cgi-bin/file4.py?a=b?c=d')
self.assertEqual(
(b'a=b?c=d' + self.linesep, 'text/html', HTTPStatus.OK),
(res.read(), res.getheader('Content-type'), res.status))

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; AssertionError: Tuples differ: (b"k=aa%2F%2Fbb&//q//p//=//a//b//\n", "text/html", <HTTPStatus.OK: 200>) != (b"", None, 200)')
def test_query_with_continuous_slashes(self):
res = self.request('/cgi-bin/file4.py?k=aa%2F%2Fbb&//q//p//=//a//b//')
self.assertEqual(
(b'k=aa%2F%2Fbb&//q//p//=//a//b//' + self.linesep,
'text/html', HTTPStatus.OK),
(res.read(), res.getheader('Content-type'), res.status))

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; Tuples differ: (b"", None, 200) != (b"Hello World\n", "text/html", <HTTPStatus.OK: 200>)')
def test_cgi_path_in_sub_directories(self):
try:
CGIHTTPRequestHandler.cgi_directories.append('/sub/dir/cgi-bin')
Expand All @@ -1104,7 +1092,6 @@ def test_cgi_path_in_sub_directories(self):
finally:
CGIHTTPRequestHandler.cgi_directories.remove('/sub/dir/cgi-bin')

@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON; AssertionError: b"HTTP_ACCEPT=text/html,text/plain" not found in b""')
def test_accept(self):
browser_accept = \
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ def test_main_thread_after_fork(self):
"main ident True\n"
"current is main True\n")

@unittest.skip("TODO: RUSTPYTHON flaky; process timeout after fork")
@skip_unless_reliable_fork
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
def test_main_thread_after_fork_from_nonmain_thread(self):
Expand Down
22 changes: 19 additions & 3 deletions crates/vm/src/stdlib/nt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ pub use module::raw_set_handle_inheritable;
#[pymodule(name = "nt", with(super::os::_os))]
pub(crate) mod module {
use crate::{
Py, PyResult, TryFromObject, VirtualMachine,
Py, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
builtins::{PyBaseExceptionRef, PyDictRef, PyListRef, PyStrRef, PyTupleRef},
common::{crt_fd, suppress_iph, windows::ToWideString},
convert::ToPyException,
exceptions::OSErrorBuilder,
function::{Either, OptionalArg},
function::{ArgMapping, Either, OptionalArg},
ospath::{OsPath, OsPathOrFd},
stdlib::os::{_os, DirFd, SupportFunc, TargetIsDirectory},
};
Expand Down Expand Up @@ -1212,12 +1212,27 @@ pub(crate) mod module {
}
}

fn envobj_to_dict(env: ArgMapping, vm: &VirtualMachine) -> PyResult<PyDictRef> {
let obj = env.obj();
if let Some(dict) = obj.downcast_ref_if_exact::<crate::builtins::PyDict>(vm) {
return Ok(dict.to_owned());
}
let keys = vm.call_method(obj, "keys", ())?;
let dict = vm.ctx.new_dict();
for key in keys.get_iter(vm)?.into_iter::<PyObjectRef>(vm)? {
let key = key?;
let val = obj.get_item(&*key, vm)?;
dict.set_item(&*key, val, vm)?;
}
Ok(dict)
}

#[cfg(target_env = "msvc")]
#[pyfunction]
fn execve(
path: OsPath,
argv: Either<PyListRef, PyTupleRef>,
env: PyDictRef,
env: ArgMapping,
vm: &VirtualMachine,
) -> PyResult<()> {
use core::iter::once;
Expand Down Expand Up @@ -1246,6 +1261,7 @@ pub(crate) mod module {
.chain(once(core::ptr::null()))
.collect();

let env = envobj_to_dict(env, vm)?;
// Build environment strings as "KEY=VALUE\0" wide strings
let mut env_strings: Vec<widestring::WideCString> = Vec::new();
for (key, value) in env.into_iter() {
Expand Down
20 changes: 18 additions & 2 deletions crates/vm/src/stdlib/posix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub mod module {
builtins::{PyDictRef, PyInt, PyListRef, PyStr, PyTupleRef},
convert::{IntoPyException, ToPyObject, TryFromObject},
exceptions::OSErrorBuilder,
function::{Either, KwArgs, OptionalArg},
function::{ArgMapping, Either, KwArgs, OptionalArg},
ospath::{OsPath, OsPathOrFd},
stdlib::os::{
_os, DirFd, FollowSymlinks, SupportFunc, TargetIsDirectory, fs_metadata,
Expand Down Expand Up @@ -1073,11 +1073,26 @@ pub mod module {
.map_err(|err| err.into_pyexception(vm))
}

fn envobj_to_dict(env: ArgMapping, vm: &VirtualMachine) -> PyResult<PyDictRef> {
let obj = env.obj();
if let Some(dict) = obj.downcast_ref_if_exact::<crate::builtins::PyDict>(vm) {
return Ok(dict.to_owned());
}
let keys = vm.call_method(obj, "keys", ())?;
let dict = vm.ctx.new_dict();
for key in keys.get_iter(vm)?.into_iter::<PyObjectRef>(vm)? {
let key = key?;
let val = obj.get_item(&*key, vm)?;
dict.set_item(&*key, val, vm)?;
}
Ok(dict)
}

#[pyfunction]
fn execve(
path: OsPath,
argv: Either<PyListRef, PyTupleRef>,
env: PyDictRef,
env: ArgMapping,
vm: &VirtualMachine,
) -> PyResult<()> {
let path = path.into_cstring(vm)?;
Expand All @@ -1095,6 +1110,7 @@ pub mod module {
return Err(vm.new_value_error("execve() arg 2 first element cannot be empty"));
}

let env = envobj_to_dict(env, vm)?;
let env = env
.into_iter()
.map(|(k, v)| -> PyResult<_> {
Expand Down
Loading