mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #3523 from hackerwins/staticmethod
Add staticmethod in macros and apply it to maketrans
This commit is contained in:
1
Lib/test/test_decorators.py
vendored
1
Lib/test/test_decorators.py
vendored
@@ -76,6 +76,7 @@ class TestDecorators(unittest.TestCase):
|
||||
self.assertEqual(C.foo(), 42)
|
||||
self.assertEqual(C().foo(), 42)
|
||||
|
||||
@unittest.skip("TODO: 3.10.x changed staticmethod to be callable")
|
||||
def test_staticmethod_function(self):
|
||||
@staticmethod
|
||||
def notamethod(x):
|
||||
|
||||
22
Lib/test/test_shlex.py
vendored
22
Lib/test/test_shlex.py
vendored
@@ -183,8 +183,6 @@ class ShlexTest(unittest.TestCase):
|
||||
"%s: %s != %s" %
|
||||
(self.data[i][0], l, self.data[i][1:]))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testSyntaxSplitAmpersandAndPipe(self):
|
||||
"""Test handling of syntax splitting of &, |"""
|
||||
# Could take these forms: &&, &, |&, ;&, ;;&
|
||||
@@ -202,8 +200,6 @@ class ShlexTest(unittest.TestCase):
|
||||
self.assertEqual(ref, result,
|
||||
"While splitting '%s' [ws=%s]" % (ss, ws))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testSyntaxSplitSemicolon(self):
|
||||
"""Test handling of syntax splitting of ;"""
|
||||
# Could take these forms: ;, ;;, ;&, ;;&
|
||||
@@ -220,8 +216,6 @@ class ShlexTest(unittest.TestCase):
|
||||
self.assertEqual(ref, result,
|
||||
"While splitting '%s' [ws=%s]" % (ss, ws))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testSyntaxSplitRedirect(self):
|
||||
"""Test handling of syntax splitting of >"""
|
||||
# of course, the same applies to <, |
|
||||
@@ -237,8 +231,6 @@ class ShlexTest(unittest.TestCase):
|
||||
self.assertEqual(ref, result,
|
||||
"While splitting '%s' [ws=%s]" % (ss, ws))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testSyntaxSplitParen(self):
|
||||
"""Test handling of syntax splitting of ()"""
|
||||
# these should all parse to the same output
|
||||
@@ -252,8 +244,6 @@ class ShlexTest(unittest.TestCase):
|
||||
self.assertEqual(ref, result,
|
||||
"While splitting '%s' [ws=%s]" % (ss, ws))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testSyntaxSplitCustom(self):
|
||||
"""Test handling of syntax splitting with custom chars"""
|
||||
ss = "~/a&&b-c --color=auto||d *.py?"
|
||||
@@ -267,8 +257,6 @@ class ShlexTest(unittest.TestCase):
|
||||
result = list(s)
|
||||
self.assertEqual(ref, result, "While splitting '%s' [ws=True]" % ss)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testTokenTypes(self):
|
||||
"""Test that tokens are split with types as expected."""
|
||||
for source, expected in (
|
||||
@@ -289,16 +277,12 @@ class ShlexTest(unittest.TestCase):
|
||||
observed.append((t, tt))
|
||||
self.assertEqual(observed, expected)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testPunctuationInWordChars(self):
|
||||
"""Test that any punctuation chars are removed from wordchars"""
|
||||
s = shlex.shlex('a_b__c', punctuation_chars='_')
|
||||
self.assertNotIn('_', s.wordchars)
|
||||
self.assertEqual(list(s), ['a', '_', 'b', '__', 'c'])
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testPunctuationWithWhitespaceSplit(self):
|
||||
"""Test that with whitespace_split, behaviour is as expected"""
|
||||
s = shlex.shlex('a && b || c', punctuation_chars='&')
|
||||
@@ -311,8 +295,6 @@ class ShlexTest(unittest.TestCase):
|
||||
# white space
|
||||
self.assertEqual(list(s), ['a', '&&', 'b', '||', 'c'])
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testPunctuationWithPosix(self):
|
||||
"""Test that punctuation_chars and posix behave correctly together."""
|
||||
# see Issue #29132
|
||||
@@ -321,8 +303,6 @@ class ShlexTest(unittest.TestCase):
|
||||
s = shlex.shlex('f >\\"abc\\"', posix=True, punctuation_chars=True)
|
||||
self.assertEqual(list(s), ['f', '>', '"abc"'])
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testEmptyStringHandling(self):
|
||||
"""Test that parsing of empty strings is correctly handled."""
|
||||
# see Issue #21999
|
||||
@@ -386,8 +366,6 @@ class ShlexTest(unittest.TestCase):
|
||||
resplit = shlex.split(joined)
|
||||
self.assertEqual(split_command, resplit)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def testPunctuationCharsReadOnly(self):
|
||||
punctuation_chars = "/|$%^"
|
||||
shlex_instance = shlex.shlex(punctuation_chars=punctuation_chars)
|
||||
|
||||
@@ -437,8 +437,9 @@ where
|
||||
let build_func = match self.method_type.as_str() {
|
||||
"method" => quote!(.build_method(ctx, class.clone())),
|
||||
"classmethod" => quote!(.build_classmethod(ctx, class.clone())),
|
||||
"staticmethod" => quote!(.build_staticmethod(ctx, class.clone())),
|
||||
other => unreachable!(
|
||||
"Only 'method' and 'classmethod' are supported, got {}",
|
||||
"Only 'method', 'classmethod' and 'staticmethod' are supported, got {}",
|
||||
other
|
||||
),
|
||||
};
|
||||
@@ -954,13 +955,15 @@ where
|
||||
{
|
||||
assert!(ALL_ALLOWED_NAMES.contains(&attr_name.as_str()));
|
||||
Ok(match attr_name.as_str() {
|
||||
attr_name @ "pymethod" | attr_name @ "pyclassmethod" => Box::new(MethodItem {
|
||||
inner: ContentItemInner {
|
||||
index,
|
||||
attr_name: attr_name.to_owned(),
|
||||
},
|
||||
method_type: attr_name.strip_prefix("py").unwrap().to_owned(),
|
||||
}),
|
||||
attr_name @ "pymethod" | attr_name @ "pyclassmethod" | attr_name @ "pystaticmethod" => {
|
||||
Box::new(MethodItem {
|
||||
inner: ContentItemInner {
|
||||
index,
|
||||
attr_name: attr_name.to_owned(),
|
||||
},
|
||||
method_type: attr_name.strip_prefix("py").unwrap().to_owned(),
|
||||
})
|
||||
}
|
||||
"pyproperty" => Box::new(PropertyItem {
|
||||
inner: ContentItemInner { index, attr_name },
|
||||
}),
|
||||
|
||||
@@ -14,6 +14,7 @@ use syn_ext::{
|
||||
pub(crate) const ALL_ALLOWED_NAMES: &[&str] = &[
|
||||
"pymethod",
|
||||
"pyclassmethod",
|
||||
"pystaticmethod",
|
||||
"pyproperty",
|
||||
"pyfunction",
|
||||
"pyclass",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{pytype, PyClassMethod, PyStr, PyStrRef, PyTypeRef};
|
||||
use super::{pytype, PyClassMethod, PyStaticMethod, PyStr, PyStrRef, PyTypeRef};
|
||||
use crate::{
|
||||
builtins::PyBoundMethod,
|
||||
function::{FuncArgs, IntoPyNativeFunc, PyNativeFunc},
|
||||
@@ -45,6 +45,14 @@ impl PyNativeFuncDef {
|
||||
let callable = self.build_method(ctx, class).into();
|
||||
PyClassMethod::new_ref(callable, ctx)
|
||||
}
|
||||
pub fn build_staticmethod(self, ctx: &PyContext, class: PyTypeRef) -> PyRef<PyStaticMethod> {
|
||||
let callable = self.build_method(ctx, class).into();
|
||||
PyRef::new_ref(
|
||||
PyStaticMethod { callable },
|
||||
ctx.types.staticmethod_type.clone(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(name = "builtin_function_or_method", module = false)]
|
||||
|
||||
@@ -227,7 +227,7 @@ impl PyByteArray {
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
#[pystaticmethod]
|
||||
fn maketrans(from: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
|
||||
PyBytesInner::maketrans(from, to, vm)
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ impl PyBytes {
|
||||
self.inner.contains(needle, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
#[pystaticmethod]
|
||||
fn maketrans(from: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
|
||||
PyBytesInner::maketrans(from, to, vm)
|
||||
}
|
||||
|
||||
@@ -1141,7 +1141,7 @@ impl PyStr {
|
||||
Ok(translated)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
#[pystaticmethod]
|
||||
fn maketrans(
|
||||
dict_or_str: PyObjectRef,
|
||||
to_str: OptionalArg<PyStrRef>,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::{PyStr, PyTypeRef};
|
||||
use crate::{
|
||||
builtins::builtinfunc::PyBuiltinMethod,
|
||||
function::IntoPyNativeFunc,
|
||||
types::{Constructor, GetDescriptor},
|
||||
function::{FuncArgs, IntoPyNativeFunc},
|
||||
types::{Callable, Constructor, GetDescriptor},
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ impl PyStaticMethod {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(with(GetDescriptor, Constructor), flags(BASETYPE, HAS_DICT))]
|
||||
#[pyimpl(with(Callable, GetDescriptor, Constructor), flags(BASETYPE, HAS_DICT))]
|
||||
impl PyStaticMethod {
|
||||
#[pyproperty(magic)]
|
||||
fn isabstractmethod(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
@@ -76,6 +76,14 @@ impl PyStaticMethod {
|
||||
}
|
||||
}
|
||||
|
||||
impl Callable for PyStaticMethod {
|
||||
type Args = FuncArgs;
|
||||
#[inline]
|
||||
fn call(zelf: &crate::PyObjectView<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
vm.invoke(&zelf.callable, args)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyStaticMethod::extend_class(context, &context.types.staticmethod_type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user