mirror of
https://github.com/pocketpy/pocketpy
synced 2026-02-03 22:20:16 +00:00
Compare commits
2 Commits
979addecf9
...
48b70c944e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48b70c944e | ||
|
|
2281b9bb44 |
@ -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,6 @@ typedef struct TypePointer {
|
||||
} TypePointer;
|
||||
|
||||
typedef struct py_ModuleInfo {
|
||||
c11_string* name;
|
||||
c11_string* package;
|
||||
c11_string* path;
|
||||
py_GlobalRef self; // weakref to the original module object
|
||||
|
||||
@ -57,7 +57,6 @@ MAGIC_METHOD(__exit__)
|
||||
MAGIC_METHOD(__name__)
|
||||
MAGIC_METHOD(__all__)
|
||||
MAGIC_METHOD(__package__)
|
||||
MAGIC_METHOD(__path__)
|
||||
MAGIC_METHOD(__class__)
|
||||
MAGIC_METHOD(__getattr__)
|
||||
MAGIC_METHOD(__reduce__)
|
||||
|
||||
@ -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__);
|
||||
|
||||
@ -2462,17 +2462,50 @@ static Error* compile_decorated(Compiler* self) {
|
||||
|
||||
// import a [as b]
|
||||
// import a [as b], c [as d]
|
||||
static Error* compile_normal_import(Compiler* self) {
|
||||
static Error* compile_normal_import(Compiler* self, c11_sbuf* buf) {
|
||||
do {
|
||||
consume(TK_ID);
|
||||
c11_sv name = Token__sv(prev());
|
||||
int index = Ctx__add_const_string(ctx(), name);
|
||||
Ctx__emit_(ctx(), OP_IMPORT_PATH, index, prev()->line);
|
||||
if(match(TK_AS)) {
|
||||
c11_sbuf__write_sv(buf, name);
|
||||
bool has_sub_cpnt = false;
|
||||
|
||||
while(match(TK_DOT)) {
|
||||
has_sub_cpnt = true;
|
||||
consume(TK_ID);
|
||||
name = Token__sv(prev());
|
||||
c11_sbuf__write_char(buf, '.');
|
||||
c11_sbuf__write_sv(buf, Token__sv(prev()));
|
||||
}
|
||||
Ctx__emit_store_name(ctx(), name_scope(self), py_namev(name), prev()->line);
|
||||
|
||||
c11_string* path = c11_sbuf__submit(buf);
|
||||
int path_index = Ctx__add_const_string(ctx(), c11_string__sv(path));
|
||||
c11_string__delete(path);
|
||||
|
||||
NameScope scope = name_scope(self);
|
||||
|
||||
Ctx__emit_(ctx(), OP_IMPORT_PATH, path_index, prev()->line);
|
||||
// [module <path>]
|
||||
|
||||
if(!has_sub_cpnt) {
|
||||
if(match(TK_AS)) {
|
||||
// import a as x
|
||||
consume(TK_ID);
|
||||
name = Token__sv(prev());
|
||||
} else {
|
||||
// import a
|
||||
}
|
||||
} else {
|
||||
if(match(TK_AS)) {
|
||||
// import a.b as x
|
||||
consume(TK_ID);
|
||||
name = Token__sv(prev());
|
||||
} else {
|
||||
// import a.b
|
||||
Ctx__emit_(ctx(), OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||
int index = Ctx__add_const_string(ctx(), name);
|
||||
Ctx__emit_(ctx(), OP_IMPORT_PATH, index, BC_KEEPLINE);
|
||||
}
|
||||
}
|
||||
Ctx__emit_store_name(ctx(), scope, py_namev(name), BC_KEEPLINE);
|
||||
} while(match(TK_COMMA));
|
||||
consume_end_stmt();
|
||||
return NULL;
|
||||
@ -2485,7 +2518,7 @@ static Error* compile_normal_import(Compiler* self) {
|
||||
// from ..a import b [as c]
|
||||
// from .a.b import c [as d]
|
||||
// from xxx import *
|
||||
static Error* compile_from_import(c11_sbuf* buf, Compiler* self) {
|
||||
static Error* compile_from_import(Compiler* self, c11_sbuf* buf) {
|
||||
int dots = 0;
|
||||
|
||||
while(true) {
|
||||
@ -2695,11 +2728,18 @@ static Error* compile_stmt(Compiler* self) {
|
||||
}
|
||||
case TK_WHILE: check(compile_while_loop(self)); break;
|
||||
case TK_FOR: check(compile_for_loop(self)); break;
|
||||
case TK_IMPORT: check(compile_normal_import(self)); break;
|
||||
case TK_IMPORT: {
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
err = compile_normal_import(self, &buf);
|
||||
c11_sbuf__dtor(&buf);
|
||||
if(err) return err;
|
||||
break;
|
||||
}
|
||||
case TK_FROM: {
|
||||
c11_sbuf buf;
|
||||
c11_sbuf__ctor(&buf);
|
||||
err = compile_from_import(&buf, self);
|
||||
err = compile_from_import(self, &buf);
|
||||
c11_sbuf__dtor(&buf);
|
||||
if(err) return err;
|
||||
break;
|
||||
|
||||
@ -465,10 +465,12 @@ static bool builtins_compile(int argc, py_Ref argv) {
|
||||
static bool builtins__import__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
PY_CHECK_ARG_TYPE(0, tp_str);
|
||||
int res = py_import(py_tostr(argv));
|
||||
const char* path = py_tostr(py_arg(0));
|
||||
if(path[0] == '.') return ValueError("relative import not allowed here");
|
||||
int res = py_import(path);
|
||||
if(res == -1) return false;
|
||||
if(res) return true;
|
||||
return ImportError("module '%s' not found", py_tostr(argv));
|
||||
return ImportError("module '%s' not found", path);
|
||||
}
|
||||
|
||||
static bool NoneType__repr__(int argc, py_Ref argv) {
|
||||
|
||||
@ -13,20 +13,18 @@ py_Ref py_getmodule(const char* path) {
|
||||
return BinTree__try_get(&vm->modules, (void*)path);
|
||||
}
|
||||
|
||||
py_Ref py_newmodule(const char* path) {
|
||||
int path_len = strlen(path);
|
||||
if(path_len > PK_MAX_MODULE_PATH_LEN) c11__abort("module path too long: %s", path);
|
||||
if(path_len == 0) c11__abort("module path cannot be empty");
|
||||
static py_Ref pk_newmodule(const char* path, bool is_init) {
|
||||
c11_sv pathv = {path, strlen(path)};
|
||||
if(pathv.size > PK_MAX_MODULE_PATH_LEN) c11__abort("module path too long: %s", path);
|
||||
if(pathv.size == 0) c11__abort("module path cannot be empty");
|
||||
|
||||
py_ModuleInfo* mi = py_newobject(py_retval(), tp_module, -1, sizeof(py_ModuleInfo));
|
||||
|
||||
int last_dot = c11_sv__rindex((c11_sv){path, path_len}, '.');
|
||||
if(last_dot == -1) {
|
||||
mi->name = c11_string__new(path);
|
||||
mi->package = c11_string__new("");
|
||||
|
||||
int last_dot = c11_sv__rindex(pathv, '.');
|
||||
if(last_dot == -1 || is_init) {
|
||||
mi->package = c11_string__new(path);
|
||||
} else {
|
||||
const char* start = path + last_dot + 1;
|
||||
mi->name = c11_string__new(start);
|
||||
// a.b.c -> a.b
|
||||
mi->package = c11_string__new2(path, last_dot);
|
||||
}
|
||||
|
||||
@ -43,16 +41,17 @@ py_Ref py_newmodule(const char* path) {
|
||||
mi->self = retval;
|
||||
|
||||
// setup __name__
|
||||
py_newstrv(py_emplacedict(retval, __name__), c11_string__sv(mi->name));
|
||||
py_newstrv(py_emplacedict(retval, __name__), c11_string__sv(mi->path));
|
||||
// setup __package__
|
||||
py_newstrv(py_emplacedict(retval, __package__), c11_string__sv(mi->package));
|
||||
// setup __path__
|
||||
py_newstrv(py_emplacedict(retval, __path__), c11_string__sv(mi->path));
|
||||
return retval;
|
||||
}
|
||||
|
||||
py_Ref py_newmodule(const char* path) {
|
||||
return pk_newmodule(path, false);
|
||||
}
|
||||
|
||||
static void py_ModuleInfo__dtor(py_ModuleInfo* mi) {
|
||||
c11_string__delete(mi->name);
|
||||
c11_string__delete(mi->package);
|
||||
c11_string__delete(mi->path);
|
||||
}
|
||||
@ -71,27 +70,28 @@ int py_import(const char* path_cstr) {
|
||||
ValueError("empty module name");
|
||||
return -1;
|
||||
}
|
||||
if(path.size > PK_MAX_MODULE_PATH_LEN) {
|
||||
ValueError("module name too long: %v", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(path.data[0] == '.') {
|
||||
c11__rtassert(vm->top_frame != NULL && vm->top_frame->module != NULL);
|
||||
|
||||
// try relative import
|
||||
int dot_count = 1;
|
||||
while(dot_count < path.size && path.data[dot_count] == '.')
|
||||
dot_count++;
|
||||
|
||||
// */__init__.py[c]
|
||||
c11_sv top_filepath = c11_string__sv(vm->top_frame->co->src->filename);
|
||||
c11_sv top_filename = c11_sv__filename(top_filepath);
|
||||
int is_init = c11__sveq2(top_filename, "__init__.py") || c11__sveq2(top_filename, "__init__.pyc");
|
||||
|
||||
py_ModuleInfo* mi = py_touserdata(vm->top_frame->module);
|
||||
c11_sv package_sv = c11_string__sv(mi->path);
|
||||
c11_sv package_sv = c11_string__sv(mi->package);
|
||||
if(package_sv.size == 0) {
|
||||
ImportError("attempted relative import with no known parent package");
|
||||
return -1;
|
||||
}
|
||||
|
||||
c11_vector /* T=c11_sv */ cpnts = c11_sv__split(package_sv, '.');
|
||||
for(int i = is_init; i < dot_count; i++) {
|
||||
for(int i = 1; i < dot_count; i++) {
|
||||
if(cpnts.length == 0){
|
||||
ImportError("attempted relative import beyond top-level package");
|
||||
return -1;
|
||||
@ -119,7 +119,22 @@ int py_import(const char* path_cstr) {
|
||||
return res;
|
||||
}
|
||||
|
||||
assert(path.data[0] != '.' && path.data[path.size - 1] != '.');
|
||||
c11__rtassert(path.data[0] != '.' && path.data[path.size - 1] != '.');
|
||||
|
||||
// import parent module (implicit recursion)
|
||||
int last_dot_index = c11_sv__rindex(path, '.');
|
||||
if(last_dot_index >= 0) {
|
||||
c11_sv ppath = c11_sv__slice2(path, 0, last_dot_index);
|
||||
py_GlobalRef ext_mod = py_getmodule(ppath.data);
|
||||
if(!ext_mod) {
|
||||
char buf[PK_MAX_MODULE_PATH_LEN + 1];
|
||||
memcpy(buf, ppath.data, ppath.size);
|
||||
buf[ppath.size] = '\0';
|
||||
int res = py_import(buf);
|
||||
if(res != 1) return res;
|
||||
py_newnil(py_retval());
|
||||
}
|
||||
}
|
||||
|
||||
// check existing module
|
||||
py_GlobalRef ext_mod = py_getmodule(path.data);
|
||||
@ -143,6 +158,7 @@ int py_import(const char* path_cstr) {
|
||||
|
||||
bool need_free = true;
|
||||
bool is_pyc = false;
|
||||
bool is_init = false;
|
||||
const char* data = load_kPythonLib(path_cstr);
|
||||
int data_size = -1;
|
||||
|
||||
@ -165,13 +181,17 @@ int py_import(const char* path_cstr) {
|
||||
c11_string__delete(filename);
|
||||
filename = c11_string__new3("%s%c__init__.py", slashed_path->data, PK_PLATFORM_SEP);
|
||||
data = vm->callbacks.importfile(filename->data, &data_size);
|
||||
if(data != NULL) goto __SUCCESS;
|
||||
if(data != NULL) {
|
||||
is_init = true;
|
||||
goto __SUCCESS;
|
||||
}
|
||||
|
||||
c11_string__delete(filename);
|
||||
filename = c11_string__new3("%s%c__init__.pyc", slashed_path->data, PK_PLATFORM_SEP);
|
||||
data = vm->callbacks.importfile(filename->data, &data_size);
|
||||
if(data != NULL) {
|
||||
is_pyc = true;
|
||||
is_init = true;
|
||||
goto __SUCCESS;
|
||||
}
|
||||
|
||||
@ -184,7 +204,7 @@ __SUCCESS:
|
||||
do {
|
||||
} while(0);
|
||||
|
||||
py_GlobalRef mod = py_newmodule(path_cstr);
|
||||
py_GlobalRef mod = pk_newmodule(path_cstr, is_init);
|
||||
|
||||
bool ok;
|
||||
if(is_pyc) {
|
||||
|
||||
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"
|
||||
@ -166,16 +166,3 @@ for i in range(len(data)):
|
||||
if i % 3 == 0:
|
||||
y = b.pop()
|
||||
delattr(a, y)
|
||||
|
||||
# bug test
|
||||
d = {
|
||||
'__name__': '__main__',
|
||||
'__package__': '',
|
||||
'__path__': '__main__',
|
||||
'a': [],
|
||||
'gc': 1,
|
||||
}
|
||||
|
||||
del d['a']
|
||||
assert 'a' not in d
|
||||
assert d['gc'] == 1
|
||||
@ -14,14 +14,13 @@ else:
|
||||
assert os.getcwd().endswith('tests')
|
||||
|
||||
import test1
|
||||
|
||||
assert test1.add(1, 2) == 13
|
||||
|
||||
from test2.a.g import get_value, A
|
||||
assert get_value() == '123'
|
||||
assert (A.__module__ == 'test2.a.g'), A.__module__
|
||||
|
||||
import test2
|
||||
import test2.a.g
|
||||
assert test2.a.g.get_value() == '123'
|
||||
|
||||
from test2.utils import get_value_2
|
||||
@ -30,10 +29,12 @@ assert get_value_2() == '123'
|
||||
from test3.a.b import value
|
||||
assert value == 1
|
||||
|
||||
import test3.a.b as test3_ab
|
||||
assert test3_ab.value == 1
|
||||
|
||||
from test2.utils import r
|
||||
assert r.__name__ == 'r'
|
||||
assert r.__name__ == 'test2.utils.r'
|
||||
assert r.__package__ == 'test2.utils'
|
||||
assert r.__path__ == 'test2.utils.r'
|
||||
|
||||
def f():
|
||||
import math as m
|
||||
|
||||
25
tests/301_import1.py
Normal file
25
tests/301_import1.py
Normal file
@ -0,0 +1,25 @@
|
||||
try:
|
||||
import os
|
||||
except ImportError:
|
||||
exit(0)
|
||||
|
||||
import sys
|
||||
is_pyc = sys.argv[0].endswith('.pyc')
|
||||
|
||||
if is_pyc:
|
||||
os.chdir('tmp/tests')
|
||||
else:
|
||||
os.chdir('tests')
|
||||
|
||||
assert os.getcwd().endswith('tests')
|
||||
|
||||
os.environ['STDOUT'] = ''
|
||||
|
||||
import test.a.g.q
|
||||
|
||||
assert os.environ['STDOUT'] == 'test init!!\ntest.a init!!\ntest.a.g init!!\ntest.a.g.q init!!\n'
|
||||
|
||||
import test
|
||||
|
||||
assert test.__package__ == 'test'
|
||||
assert test.__name__ == 'test'
|
||||
@ -1,46 +0,0 @@
|
||||
# a=[]
|
||||
# import gc
|
||||
# gc.collect()
|
||||
|
||||
# # a.append(a)
|
||||
# print(globals().items())
|
||||
# del a
|
||||
# print(list(globals().items()))
|
||||
# print(globals()['gc'])
|
||||
# gc.collect()
|
||||
|
||||
d = object()
|
||||
d.__name__ = '__main__'
|
||||
d.__package__ = ''
|
||||
d.__path__ = '__main__'
|
||||
d.a = []
|
||||
d.gc = 1
|
||||
|
||||
assert d.gc == 1
|
||||
del d.a
|
||||
|
||||
assert not hasattr(d, 'a')
|
||||
assert d.gc == 1
|
||||
|
||||
# [0, 1, 6, 7, 4, 5, 2, 3]
|
||||
|
||||
# 0 __name__ [0]
|
||||
# 1 __package__ [1]
|
||||
# 2 nil
|
||||
# 3 nil
|
||||
# 4 gc [4]
|
||||
# 5 nil
|
||||
# 6 __path__ [2]
|
||||
# 7 a [3]
|
||||
|
||||
import gc
|
||||
gc.collect()
|
||||
|
||||
a = []
|
||||
del a
|
||||
assert gc.collect() == 1
|
||||
|
||||
a = []
|
||||
a.append(a)
|
||||
del a
|
||||
assert gc.collect() == 1
|
||||
5
tests/test/__init__.py
Normal file
5
tests/test/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
assert __package__ == 'test'
|
||||
assert __name__ == 'test'
|
||||
|
||||
import os
|
||||
os.environ['STDOUT'] += 'test init!!\n'
|
||||
5
tests/test/a/__init__.py
Normal file
5
tests/test/a/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
assert __package__ == 'test.a'
|
||||
assert __name__ == 'test.a'
|
||||
|
||||
import os
|
||||
os.environ['STDOUT'] += 'test.a init!!\n'
|
||||
7
tests/test/a/g/__init__.py
Normal file
7
tests/test/a/g/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
assert __package__ == 'test.a.g'
|
||||
assert __name__ == 'test.a.g'
|
||||
|
||||
import os
|
||||
os.environ['STDOUT'] += 'test.a.g init!!\n'
|
||||
|
||||
|
||||
5
tests/test/a/g/q.py
Normal file
5
tests/test/a/g/q.py
Normal file
@ -0,0 +1,5 @@
|
||||
assert __package__ == 'test.a.g'
|
||||
assert __name__ == 'test.a.g.q'
|
||||
|
||||
import os
|
||||
os.environ['STDOUT'] += 'test.a.g.q init!!\n'
|
||||
@ -1,7 +1,7 @@
|
||||
D = 10
|
||||
|
||||
try:
|
||||
import abc # does not exist
|
||||
import xxxxx # does not exist
|
||||
exit(1)
|
||||
except ImportError:
|
||||
pass
|
||||
@ -1,3 +0,0 @@
|
||||
raise ValueError(
|
||||
"test3 should not be imported"
|
||||
)
|
||||
@ -1,3 +0,0 @@
|
||||
raise ValueError(
|
||||
"test3.a should not be imported"
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user