mirror of
https://github.com/pocketpy/pocketpy
synced 2026-02-03 22:20:16 +00:00
fix #426
This commit is contained in:
parent
2281b9bb44
commit
48b70c944e
@ -3,7 +3,7 @@ output: .retype
|
||||
url: https://pocketpy.dev
|
||||
branding:
|
||||
title: pocketpy
|
||||
label: v2.1.7
|
||||
label: v2.1.8
|
||||
logo: "./static/logo.png"
|
||||
favicon: "./static/logo.png"
|
||||
meta:
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
// clang-format off
|
||||
|
||||
#define PK_VERSION "2.1.7"
|
||||
#define PK_VERSION "2.1.8"
|
||||
#define PK_VERSION_MAJOR 2
|
||||
#define PK_VERSION_MINOR 1
|
||||
#define PK_VERSION_PATCH 7
|
||||
#define PK_VERSION_PATCH 8
|
||||
|
||||
/*************** feature settings ***************/
|
||||
#ifndef PK_ENABLE_OS // can be overridden by cmake
|
||||
|
||||
@ -35,7 +35,7 @@ A new Flutter FFI plugin project.
|
||||
|
||||
s.prepare_command = <<-CMD
|
||||
rm -rf pocketpy
|
||||
git clone --branch v2.1.7 --depth 1 https://github.com/pocketpy/pocketpy.git
|
||||
git clone --branch v2.1.8 --depth 1 https://github.com/pocketpy/pocketpy.git
|
||||
cd pocketpy
|
||||
git submodule update --init --recursive --depth 1
|
||||
bash build_ios_libs.sh
|
||||
|
||||
@ -32,7 +32,7 @@ A new Flutter FFI plugin project.
|
||||
|
||||
s.prepare_command = <<-CMD
|
||||
rm -rf pocketpy
|
||||
git clone --branch v2.1.7 --depth 1 https://github.com/pocketpy/pocketpy.git
|
||||
git clone --branch v2.1.8 --depth 1 https://github.com/pocketpy/pocketpy.git
|
||||
cd pocketpy
|
||||
git submodule update --init --recursive --depth 1
|
||||
bash build_darwin_libs.sh
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
name: pocketpy
|
||||
description: A lightweight Python interpreter for game engines. It supports Android/iOS/Windows/Linux/MacOS.
|
||||
version: 2.1.7
|
||||
version: 2.1.8
|
||||
homepage: https://pocketpy.dev
|
||||
repository: https://github.com/pocketpy/pocketpy
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ set(PK_BUILD_SHARED_LIB ON CACHE BOOL "" FORCE)
|
||||
FetchContent_Declare(
|
||||
pocketpy
|
||||
GIT_REPOSITORY https://github.com/pocketpy/pocketpy.git
|
||||
GIT_TAG v2.1.7
|
||||
GIT_TAG v2.1.8
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(pocketpy)
|
||||
|
||||
@ -41,6 +41,116 @@ static bool str__len__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool str__mod__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
c11_string* self = pk_tostr(&argv[0]);
|
||||
// %s
|
||||
// %d %i
|
||||
// %f
|
||||
// %r
|
||||
// %%
|
||||
py_TValue* args;
|
||||
int args_count;
|
||||
if(py_istype(&argv[1], tp_tuple)) {
|
||||
args_count = py_tuple_len(&argv[1]);
|
||||
args = py_tuple_data(&argv[1]);
|
||||
} else {
|
||||
args_count = 1;
|
||||
args = &argv[1];
|
||||
}
|
||||
|
||||
int arg_index = 0;
|
||||
const char* p = self->data;
|
||||
const char* p_end = self->data + self->size;
|
||||
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
|
||||
while(p < p_end) {
|
||||
if(*p == '%') {
|
||||
p++;
|
||||
if(p >= p_end) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return ValueError("incomplete format");
|
||||
}
|
||||
char spec = *p;
|
||||
p++;
|
||||
if(spec == '%') {
|
||||
// %% -> %
|
||||
c11_sbuf__write_char(&buf, '%');
|
||||
} else if(spec == 's') {
|
||||
// %s -> string
|
||||
if(arg_index >= args_count) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return TypeError("not enough arguments for format string");
|
||||
}
|
||||
if(!py_str(&args[arg_index])) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return false;
|
||||
}
|
||||
c11_sbuf__write_sv(&buf, py_tosv(py_retval()));
|
||||
arg_index++;
|
||||
} else if(spec == 'd' || spec == 'i') {
|
||||
// %d or %i -> integer
|
||||
if(arg_index >= args_count) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return TypeError("not enough arguments for format string");
|
||||
}
|
||||
if(!py_checktype(&args[arg_index], tp_int)) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return false;
|
||||
}
|
||||
py_i64 val = py_toint(&args[arg_index]);
|
||||
c11_sbuf__write_i64(&buf, val);
|
||||
arg_index++;
|
||||
} else if(spec == 'f') {
|
||||
// %f -> float
|
||||
if(arg_index >= args_count) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return TypeError("not enough arguments for format string");
|
||||
}
|
||||
py_f64 val;
|
||||
if(py_istype(&args[arg_index], tp_float)) {
|
||||
val = py_tofloat(&args[arg_index]);
|
||||
} else if(py_istype(&args[arg_index], tp_int)) {
|
||||
val = (py_f64)py_toint(&args[arg_index]);
|
||||
} else {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return TypeError("a float is required");
|
||||
}
|
||||
c11_sbuf__write_f64(&buf, val, 6);
|
||||
arg_index++;
|
||||
} else if(spec == 'r') {
|
||||
// %r -> repr
|
||||
if(arg_index >= args_count) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return TypeError("not enough arguments for format string");
|
||||
}
|
||||
if(!py_repr(&args[arg_index])) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return false;
|
||||
}
|
||||
c11_sbuf__write_sv(&buf, py_tosv(py_retval()));
|
||||
arg_index++;
|
||||
} else {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return ValueError("unsupported format character '%c'", spec);
|
||||
}
|
||||
} else {
|
||||
c11_sbuf__write_char(&buf, *p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if(arg_index != args_count) {
|
||||
c11_sbuf__dtor(&buf);
|
||||
return TypeError("not all arguments converted during string formatting");
|
||||
}
|
||||
|
||||
c11_sbuf__py_submit(&buf, py_retval());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool str__add__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
c11_string* self = pk_tostr(&argv[0]);
|
||||
@ -503,6 +613,7 @@ py_Type pk_str__register() {
|
||||
py_bindmagic(tp_str, __new__, str__new__);
|
||||
py_bindmagic(tp_str, __hash__, str__hash__);
|
||||
py_bindmagic(tp_str, __len__, str__len__);
|
||||
py_bindmagic(tp_str, __mod__, str__mod__);
|
||||
py_bindmagic(tp_str, __add__, str__add__);
|
||||
py_bindmagic(tp_str, __mul__, str__mul__);
|
||||
py_bindmagic(tp_str, __rmul__, str__rmul__);
|
||||
|
||||
51
tests/042_str_mod.py
Normal file
51
tests/042_str_mod.py
Normal file
@ -0,0 +1,51 @@
|
||||
# Test str.__mod__ (old-style % formatting)
|
||||
|
||||
# Test %s - string formatting
|
||||
assert "hello %s" % "world" == "hello world"
|
||||
assert "%s" % 123 == "123"
|
||||
assert "%s %s" % ("a", "b") == "a b"
|
||||
assert "name: %s, age: %s" % ("Alice", 30) == "name: Alice, age: 30"
|
||||
|
||||
# Test %d - integer formatting
|
||||
assert "%d" % 42 == "42"
|
||||
assert "%d" % -123 == "-123"
|
||||
assert "%d" % 0 == "0"
|
||||
assert "count: %d" % 100 == "count: 100"
|
||||
|
||||
# Test %i - integer formatting (same as %d)
|
||||
assert "%i" % 42 == "42"
|
||||
assert "%i" % -123 == "-123"
|
||||
assert "value: %i" % 999 == "value: 999"
|
||||
|
||||
# Test %f - float formatting
|
||||
assert "%f" % 3.14 == "3.140000"
|
||||
assert "%f" % -2.5 == "-2.500000"
|
||||
assert "%f" % 0.0 == "0.000000"
|
||||
assert "%f" % 42 == "42.000000" # int to float
|
||||
|
||||
# Test %r - repr formatting
|
||||
assert "%r" % "hello" == "'hello'"
|
||||
assert "%r" % 123 == "123"
|
||||
assert "%r" % [1, 2, 3] == "[1, 2, 3]"
|
||||
|
||||
# Test %% - literal percent
|
||||
assert "%%" % () == "%"
|
||||
assert "100%%" % () == "100%"
|
||||
assert "%%s" % () == "%s"
|
||||
assert "%d%%" % 50 == "50%"
|
||||
|
||||
# Test combined format specifiers
|
||||
assert "%s is %d years old" % ("Bob", 25) == "Bob is 25 years old"
|
||||
assert "%s: %f" % ("pi", 3.14159) == "pi: 3.141590"
|
||||
assert "%d + %d = %d" % (1, 2, 3) == "1 + 2 = 3"
|
||||
assert "Hello %s! You have %d messages." % ("User", 5) == "Hello User! You have 5 messages."
|
||||
|
||||
# Test single value (not tuple)
|
||||
assert "value: %s" % "test" == "value: test"
|
||||
assert "number: %d" % 42 == "number: 42"
|
||||
|
||||
# Test empty string
|
||||
assert "" % () == ""
|
||||
|
||||
# Test no format specifiers
|
||||
assert "hello world" % () == "hello world"
|
||||
Loading…
x
Reference in New Issue
Block a user