forked from Rust-related/RustPython
Compare commits
9 Commits
update_fst
...
2024-12-30
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1abaf87abe | ||
|
|
38593fbd85 | ||
|
|
8d187fd275 | ||
|
|
646cc81656 | ||
|
|
01f7536b36 | ||
|
|
97e5ec02f8 | ||
|
|
3dced01af0 | ||
| 0cf4534c5c | |||
| 044f66fba3 |
105
.github/workflows/release.yml
vendored
Normal file
105
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
name: Release
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
CARGO_ARGS: --no-default-features --features stdlib,zlib,importlib,encodings,sqlite,ssl
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.platform.runner }}
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
- runner: ubuntu-latest
|
||||
target: x86_64-unknown-linux-gnu
|
||||
# - runner: ubuntu-latest
|
||||
# target: i686-unknown-linux-gnu
|
||||
# - runner: ubuntu-latest
|
||||
# target: aarch64-unknown-linux-gnu
|
||||
# - runner: ubuntu-latest
|
||||
# target: armv7-unknown-linux-gnueabi
|
||||
# - runner: ubuntu-latest
|
||||
# target: s390x-unknown-linux-gnu
|
||||
# - runner: ubuntu-latest
|
||||
# target: powerpc64le-unknown-linux-gnu
|
||||
- runner: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
# - runner: macos-latest
|
||||
# target: x86_64-apple-darwin
|
||||
- runner: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
# - runner: windows-latest
|
||||
# target: i686-pc-windows-msvc
|
||||
# - runner: windows-latest
|
||||
# target: aarch64-pc-windows-msvc
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Set up Environment
|
||||
shell: bash
|
||||
run: rustup target add ${{ matrix.platform.target }}
|
||||
- name: Set up Windows Environment
|
||||
shell: bash
|
||||
run: |
|
||||
cargo install --target-dir=target -v cargo-vcpkg
|
||||
cargo vcpkg -v build
|
||||
if: runner.os == 'Windows'
|
||||
- name: Set up MacOS Environment
|
||||
run: brew install autoconf automake libtool
|
||||
if: runner.os == 'macOS'
|
||||
|
||||
- name: Build RustPython
|
||||
run: cargo build --release --target=${{ matrix.platform.target }} --verbose --features=threading ${{ env.CARGO_ARGS }}
|
||||
if: runner.os == 'macOS'
|
||||
- name: Build RustPython
|
||||
run: cargo build --release --target=${{ matrix.platform.target }} --verbose --features=threading ${{ env.CARGO_ARGS }},jit
|
||||
if: runner.os != 'macOS'
|
||||
|
||||
- name: Rename Binary
|
||||
run: cp target/${{ matrix.platform.target }}/release/rustpython target/rustpython-release-${{ runner.os }}-${{ matrix.platform.target }}
|
||||
if: runner.os != 'Windows'
|
||||
- name: Rename Binary
|
||||
run: cp target/${{ matrix.platform.target }}/release/rustpython.exe target/rustpython-release-${{ runner.os }}-${{ matrix.platform.target }}.exe
|
||||
if: runner.os == 'Windows'
|
||||
|
||||
- name: Upload Binary Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: rustpython-release-${{ runner.os }}-${{ matrix.platform.target }}
|
||||
path: target/rustpython-release-${{ runner.os }}-${{ matrix.platform.target }}*
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Download Binary Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: bin
|
||||
pattern: rustpython-release-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: List Binaries
|
||||
run: |
|
||||
ls -lah bin/
|
||||
file bin/*
|
||||
- name: Create Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ github.ref_name }}
|
||||
run: ${{ github.run_number }}
|
||||
run: |
|
||||
today=$(date '+%Y-%m-%d')
|
||||
gh release create "$today-$tag-$run" \
|
||||
--repo="$GITHUB_REPOSITORY" \
|
||||
--title="RustPython Release $today-$tag #$run" \
|
||||
--target="$tag" \
|
||||
bin/rustpython-release-*
|
||||
17
Cargo.lock
generated
17
Cargo.lock
generated
@@ -1566,13 +1566,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pmutil"
|
||||
version = "0.5.3"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3894e5d549cccbe44afecf72922f277f603cd4bb0219c8342631ef18fffbe004"
|
||||
checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1824,24 +1824,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "result-like"
|
||||
version = "0.4.6"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccc7ce6435c33898517a30e85578cd204cbb696875efb93dec19a2d31294f810"
|
||||
checksum = "abf7172fef6a7d056b5c26bf6c826570267562d51697f4982ff3ba4aec68a9df"
|
||||
dependencies = [
|
||||
"result-like-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "result-like-derive"
|
||||
version = "0.4.6"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fabf0a2e54f711c68c50d49f648a1a8a37adcb57353f518ac4df374f0788f42"
|
||||
checksum = "a8d6574c02e894d66370cfc681e5d68fedbc9a548fb55b30a96b3f0ae22d0fe5"
|
||||
dependencies = [
|
||||
"pmutil",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn-ext",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
65
Lib/test/support/testcase.py
vendored
Normal file
65
Lib/test/support/testcase.py
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
from math import copysign, isnan
|
||||
|
||||
|
||||
class ExceptionIsLikeMixin:
|
||||
def assertExceptionIsLike(self, exc, template):
|
||||
"""
|
||||
Passes when the provided `exc` matches the structure of `template`.
|
||||
Individual exceptions don't have to be the same objects or even pass
|
||||
an equality test: they only need to be the same type and contain equal
|
||||
`exc_obj.args`.
|
||||
"""
|
||||
if exc is None and template is None:
|
||||
return
|
||||
|
||||
if template is None:
|
||||
self.fail(f"unexpected exception: {exc}")
|
||||
|
||||
if exc is None:
|
||||
self.fail(f"expected an exception like {template!r}, got None")
|
||||
|
||||
if not isinstance(exc, ExceptionGroup):
|
||||
self.assertEqual(exc.__class__, template.__class__)
|
||||
self.assertEqual(exc.args[0], template.args[0])
|
||||
else:
|
||||
self.assertEqual(exc.message, template.message)
|
||||
self.assertEqual(len(exc.exceptions), len(template.exceptions))
|
||||
for e, t in zip(exc.exceptions, template.exceptions):
|
||||
self.assertExceptionIsLike(e, t)
|
||||
|
||||
|
||||
class FloatsAreIdenticalMixin:
|
||||
def assertFloatsAreIdentical(self, x, y):
|
||||
"""Fail unless floats x and y are identical, in the sense that:
|
||||
(1) both x and y are nans, or
|
||||
(2) both x and y are infinities, with the same sign, or
|
||||
(3) both x and y are zeros, with the same sign, or
|
||||
(4) x and y are both finite and nonzero, and x == y
|
||||
|
||||
"""
|
||||
msg = 'floats {!r} and {!r} are not identical'
|
||||
|
||||
if isnan(x) or isnan(y):
|
||||
if isnan(x) and isnan(y):
|
||||
return
|
||||
elif x == y:
|
||||
if x != 0.0:
|
||||
return
|
||||
# both zero; check that signs match
|
||||
elif copysign(1.0, x) == copysign(1.0, y):
|
||||
return
|
||||
else:
|
||||
msg += ': zeros have different signs'
|
||||
self.fail(msg.format(x, y))
|
||||
|
||||
|
||||
class ComplexesAreIdenticalMixin(FloatsAreIdenticalMixin):
|
||||
def assertComplexesAreIdentical(self, x, y):
|
||||
"""Fail unless complex numbers x and y have equal values and signs.
|
||||
|
||||
In particular, if x and y both have real (or imaginary) part
|
||||
zero, but the zeros have different signs, this test will fail.
|
||||
|
||||
"""
|
||||
self.assertFloatsAreIdentical(x.real, y.real)
|
||||
self.assertFloatsAreIdentical(x.imag, y.imag)
|
||||
102
Lib/test/test_float.py
vendored
102
Lib/test/test_float.py
vendored
@@ -8,7 +8,7 @@ import time
|
||||
import unittest
|
||||
|
||||
from test import support
|
||||
from test.support import import_helper
|
||||
from test.support.testcase import FloatsAreIdenticalMixin
|
||||
from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
|
||||
INVALID_UNDERSCORE_LITERALS)
|
||||
from math import isinf, isnan, copysign, ldexp
|
||||
@@ -19,7 +19,6 @@ try:
|
||||
except ImportError:
|
||||
_testcapi = None
|
||||
|
||||
HAVE_IEEE_754 = float.__getformat__("double").startswith("IEEE")
|
||||
INF = float("inf")
|
||||
NAN = float("nan")
|
||||
|
||||
@@ -742,8 +741,13 @@ class FormatTestCase(unittest.TestCase):
|
||||
|
||||
lhs, rhs = map(str.strip, line.split('->'))
|
||||
fmt, arg = lhs.split()
|
||||
self.assertEqual(fmt % float(arg), rhs)
|
||||
self.assertEqual(fmt % -float(arg), '-' + rhs)
|
||||
f = float(arg)
|
||||
self.assertEqual(fmt % f, rhs)
|
||||
self.assertEqual(fmt % -f, '-' + rhs)
|
||||
if fmt != '%r':
|
||||
fmt2 = fmt[1:]
|
||||
self.assertEqual(format(f, fmt2), rhs)
|
||||
self.assertEqual(format(-f, fmt2), '-' + rhs)
|
||||
|
||||
def test_issue5864(self):
|
||||
self.assertEqual(format(123.456, '.4'), '123.5')
|
||||
@@ -833,7 +837,7 @@ class ReprTestCase(unittest.TestCase):
|
||||
self.assertEqual(repr(float(negs)), str(float(negs)))
|
||||
|
||||
@support.requires_IEEE_754
|
||||
class RoundTestCase(unittest.TestCase):
|
||||
class RoundTestCase(unittest.TestCase, FloatsAreIdenticalMixin):
|
||||
|
||||
def test_inf_nan(self):
|
||||
self.assertRaises(OverflowError, round, INF)
|
||||
@@ -863,10 +867,10 @@ class RoundTestCase(unittest.TestCase):
|
||||
|
||||
def test_small_n(self):
|
||||
for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]:
|
||||
self.assertEqual(round(123.456, n), 0.0)
|
||||
self.assertEqual(round(-123.456, n), -0.0)
|
||||
self.assertEqual(round(1e300, n), 0.0)
|
||||
self.assertEqual(round(1e-320, n), 0.0)
|
||||
self.assertFloatsAreIdentical(round(123.456, n), 0.0)
|
||||
self.assertFloatsAreIdentical(round(-123.456, n), -0.0)
|
||||
self.assertFloatsAreIdentical(round(1e300, n), 0.0)
|
||||
self.assertFloatsAreIdentical(round(1e-320, n), 0.0)
|
||||
|
||||
def test_overflow(self):
|
||||
self.assertRaises(OverflowError, round, 1.6e308, -308)
|
||||
@@ -1053,32 +1057,22 @@ class InfNanTest(unittest.TestCase):
|
||||
self.assertEqual(copysign(1.0, float('inf')), 1.0)
|
||||
self.assertEqual(copysign(1.0, float('-inf')), -1.0)
|
||||
|
||||
@unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short',
|
||||
"applies only when using short float repr style")
|
||||
def test_nan_signs(self):
|
||||
# When using the dtoa.c code, the sign of float('nan') should
|
||||
# be predictable.
|
||||
# The sign of float('nan') should be predictable.
|
||||
self.assertEqual(copysign(1.0, float('nan')), 1.0)
|
||||
self.assertEqual(copysign(1.0, float('-nan')), -1.0)
|
||||
|
||||
|
||||
fromHex = float.fromhex
|
||||
toHex = float.hex
|
||||
class HexFloatTestCase(unittest.TestCase):
|
||||
class HexFloatTestCase(FloatsAreIdenticalMixin, unittest.TestCase):
|
||||
MAX = fromHex('0x.fffffffffffff8p+1024') # max normal
|
||||
MIN = fromHex('0x1p-1022') # min normal
|
||||
TINY = fromHex('0x0.0000000000001p-1022') # min subnormal
|
||||
EPS = fromHex('0x0.0000000000001p0') # diff between 1.0 and next float up
|
||||
|
||||
def identical(self, x, y):
|
||||
# check that floats x and y are identical, or that both
|
||||
# are NaNs
|
||||
if isnan(x) or isnan(y):
|
||||
if isnan(x) == isnan(y):
|
||||
return
|
||||
elif x == y and (x != 0.0 or copysign(1.0, x) == copysign(1.0, y)):
|
||||
return
|
||||
self.fail('%r not identical to %r' % (x, y))
|
||||
self.assertFloatsAreIdentical(x, y)
|
||||
|
||||
def test_ends(self):
|
||||
self.identical(self.MIN, ldexp(1.0, -1022))
|
||||
@@ -1517,69 +1511,5 @@ class HexFloatTestCase(unittest.TestCase):
|
||||
self.assertEqual(getattr(f, 'foo', 'none'), 'bar')
|
||||
|
||||
|
||||
# Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8()
|
||||
# Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8()
|
||||
BIG_ENDIAN = 0
|
||||
LITTLE_ENDIAN = 1
|
||||
EPSILON = {
|
||||
2: 2.0 ** -11, # binary16
|
||||
4: 2.0 ** -24, # binary32
|
||||
8: 2.0 ** -53, # binary64
|
||||
}
|
||||
|
||||
@unittest.skipIf(_testcapi is None, 'needs _testcapi')
|
||||
class PackTests(unittest.TestCase):
|
||||
def test_pack(self):
|
||||
self.assertEqual(_testcapi.float_pack(2, 1.5, BIG_ENDIAN),
|
||||
b'>\x00')
|
||||
self.assertEqual(_testcapi.float_pack(4, 1.5, BIG_ENDIAN),
|
||||
b'?\xc0\x00\x00')
|
||||
self.assertEqual(_testcapi.float_pack(8, 1.5, BIG_ENDIAN),
|
||||
b'?\xf8\x00\x00\x00\x00\x00\x00')
|
||||
self.assertEqual(_testcapi.float_pack(2, 1.5, LITTLE_ENDIAN),
|
||||
b'\x00>')
|
||||
self.assertEqual(_testcapi.float_pack(4, 1.5, LITTLE_ENDIAN),
|
||||
b'\x00\x00\xc0?')
|
||||
self.assertEqual(_testcapi.float_pack(8, 1.5, LITTLE_ENDIAN),
|
||||
b'\x00\x00\x00\x00\x00\x00\xf8?')
|
||||
|
||||
def test_unpack(self):
|
||||
self.assertEqual(_testcapi.float_unpack(b'>\x00', BIG_ENDIAN),
|
||||
1.5)
|
||||
self.assertEqual(_testcapi.float_unpack(b'?\xc0\x00\x00', BIG_ENDIAN),
|
||||
1.5)
|
||||
self.assertEqual(_testcapi.float_unpack(b'?\xf8\x00\x00\x00\x00\x00\x00', BIG_ENDIAN),
|
||||
1.5)
|
||||
self.assertEqual(_testcapi.float_unpack(b'\x00>', LITTLE_ENDIAN),
|
||||
1.5)
|
||||
self.assertEqual(_testcapi.float_unpack(b'\x00\x00\xc0?', LITTLE_ENDIAN),
|
||||
1.5)
|
||||
self.assertEqual(_testcapi.float_unpack(b'\x00\x00\x00\x00\x00\x00\xf8?', LITTLE_ENDIAN),
|
||||
1.5)
|
||||
|
||||
def test_roundtrip(self):
|
||||
large = 2.0 ** 100
|
||||
values = [1.0, 1.5, large, 1.0/7, math.pi]
|
||||
if HAVE_IEEE_754:
|
||||
values.extend((INF, NAN))
|
||||
for value in values:
|
||||
for size in (2, 4, 8,):
|
||||
if size == 2 and value == large:
|
||||
# too large for 16-bit float
|
||||
continue
|
||||
rel_tol = EPSILON[size]
|
||||
for endian in (BIG_ENDIAN, LITTLE_ENDIAN):
|
||||
with self.subTest(value=value, size=size, endian=endian):
|
||||
data = _testcapi.float_pack(size, value, endian)
|
||||
value2 = _testcapi.float_unpack(data, endian)
|
||||
if isnan(value):
|
||||
self.assertTrue(isnan(value2), (value, value2))
|
||||
elif size < 8:
|
||||
self.assertTrue(math.isclose(value2, value, rel_tol=rel_tol),
|
||||
(value, value2))
|
||||
else:
|
||||
self.assertEqual(value2, value)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -32,3 +32,23 @@ assert_raises(ValueError, lambda: 1 << -1)
|
||||
|
||||
# Right shift raises value error on negative
|
||||
assert_raises(ValueError, lambda: 1 >> -1)
|
||||
|
||||
# Bitwise or, and, xor raises value error on incompatible types
|
||||
assert_raises(TypeError, lambda: "abc" | True)
|
||||
assert_raises(TypeError, lambda: "abc" & True)
|
||||
assert_raises(TypeError, lambda: "abc" ^ True)
|
||||
assert_raises(TypeError, lambda: True | "abc")
|
||||
assert_raises(TypeError, lambda: True & "abc")
|
||||
assert_raises(TypeError, lambda: True ^ "abc")
|
||||
assert_raises(TypeError, lambda: "abc" | 1.5)
|
||||
assert_raises(TypeError, lambda: "abc" & 1.5)
|
||||
assert_raises(TypeError, lambda: "abc" ^ 1.5)
|
||||
assert_raises(TypeError, lambda: 1.5 | "abc")
|
||||
assert_raises(TypeError, lambda: 1.5 & "abc")
|
||||
assert_raises(TypeError, lambda: 1.5 ^ "abc")
|
||||
assert_raises(TypeError, lambda: True | 1.5)
|
||||
assert_raises(TypeError, lambda: True & 1.5)
|
||||
assert_raises(TypeError, lambda: True ^ 1.5)
|
||||
assert_raises(TypeError, lambda: 1.5 | True)
|
||||
assert_raises(TypeError, lambda: 1.5 & True)
|
||||
assert_raises(TypeError, lambda: 1.5 ^ True)
|
||||
|
||||
@@ -502,9 +502,9 @@ with TestWithTempDir() as tmpdir:
|
||||
assert set(collected_files) == set(expected_files)
|
||||
|
||||
# system()
|
||||
if "win" not in sys.platform:
|
||||
assert os.system('ls') == 0
|
||||
assert os.system('{') != 0
|
||||
if os.name in ('posix', 'nt'):
|
||||
assert os.system('echo test') == 0
|
||||
assert os.system('&') != 0
|
||||
|
||||
for arg in [None, 1, 1.0, TabError]:
|
||||
assert_raises(TypeError, os.system, arg)
|
||||
|
||||
@@ -58,6 +58,7 @@ use std::process::ExitCode;
|
||||
pub use interpreter::InterpreterConfig;
|
||||
pub use rustpython_vm as vm;
|
||||
pub use settings::{opts_with_clap, InstallPipMode, RunMode};
|
||||
pub use shell::run_shell;
|
||||
|
||||
/// The main cli of the `rustpython` interpreter. This function will return `std::process::ExitCode`
|
||||
/// based on the return code of the python code ran through the cli.
|
||||
|
||||
@@ -78,7 +78,7 @@ flamer = { version = "0.4", optional = true }
|
||||
half = "2"
|
||||
memoffset = "0.9.1"
|
||||
optional = "0.5.0"
|
||||
result-like = "0.4.6"
|
||||
result-like = "0.5.0"
|
||||
timsort = "0.1.2"
|
||||
|
||||
## unicode stuff
|
||||
|
||||
@@ -127,8 +127,10 @@ impl PyBool {
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs || rhs).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.payload::<PyInt>() {
|
||||
lhs.or(rhs, vm).to_pyobject(vm)
|
||||
} else {
|
||||
get_py_int(&lhs).or(rhs, vm).to_pyobject(vm)
|
||||
vm.ctx.not_implemented()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +143,10 @@ impl PyBool {
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs && rhs).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.payload::<PyInt>() {
|
||||
lhs.and(rhs, vm).to_pyobject(vm)
|
||||
} else {
|
||||
get_py_int(&lhs).and(rhs, vm).to_pyobject(vm)
|
||||
vm.ctx.not_implemented()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,8 +159,10 @@ impl PyBool {
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs ^ rhs).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.payload::<PyInt>() {
|
||||
lhs.xor(rhs, vm).to_pyobject(vm)
|
||||
} else {
|
||||
get_py_int(&lhs).xor(rhs, vm).to_pyobject(vm)
|
||||
vm.ctx.not_implemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,7 +213,3 @@ pub(crate) fn init(context: &Context) {
|
||||
pub(crate) fn get_value(obj: &PyObject) -> bool {
|
||||
!obj.payload::<PyInt>().unwrap().as_bigint().is_zero()
|
||||
}
|
||||
|
||||
fn get_py_int(obj: &PyObject) -> &PyInt {
|
||||
obj.payload::<PyInt>().unwrap()
|
||||
}
|
||||
|
||||
@@ -142,6 +142,7 @@ pub(super) mod _os {
|
||||
protocol::PyIterReturn,
|
||||
recursion::ReprGuard,
|
||||
types::{IterNext, Iterable, PyStructSequence, Representable, SelfIter},
|
||||
utils::ToCString,
|
||||
vm::VirtualMachine,
|
||||
AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject,
|
||||
};
|
||||
@@ -1028,6 +1029,14 @@ pub(super) mod _os {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any(unix, windows))]
|
||||
#[pyfunction]
|
||||
fn system(command: PyStrRef, vm: &VirtualMachine) -> PyResult<i32> {
|
||||
let cstr = command.to_cstring(vm)?;
|
||||
let x = unsafe { libc::system(cstr.as_ptr()) };
|
||||
Ok(x)
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
struct UtimeArgs {
|
||||
path: OsPath,
|
||||
|
||||
@@ -901,13 +901,6 @@ pub mod module {
|
||||
nix::unistd::pipe2(oflags).map_err(|err| err.into_pyexception(vm))
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn system(command: PyStrRef, vm: &VirtualMachine) -> PyResult<i32> {
|
||||
let cstr = command.to_cstring(vm)?;
|
||||
let x = unsafe { libc::system(cstr.as_ptr()) };
|
||||
Ok(x)
|
||||
}
|
||||
|
||||
fn _chmod(
|
||||
path: OsPath,
|
||||
dir_fd: DirFd<0>,
|
||||
|
||||
Reference in New Issue
Block a user