summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/builtin.c16
-rw-r--r--py/builtinimport.c3
-rw-r--r--py/mpconfig.h5
-rw-r--r--py/obj.h11
-rw-r--r--py/objstringio.c6
-rw-r--r--py/qstrdefs.h3
-rw-r--r--py/stream.c29
7 files changed, 49 insertions, 24 deletions
diff --git a/py/builtin.c b/py/builtin.c
index 725613385a..dabc990165 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -503,7 +503,21 @@ STATIC mp_obj_t mp_builtin_sorted(uint n_args, const mp_obj_t *args, mp_map_t *k
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
STATIC mp_obj_t mp_builtin_id(mp_obj_t o_in) {
- return mp_obj_new_int((mp_int_t)o_in);
+ mp_int_t id = (mp_int_t)o_in;
+ if (!MP_OBJ_IS_OBJ(o_in)) {
+ return mp_obj_new_int(id);
+ } else if (id >= 0) {
+ // Many OSes and CPUs have affinity for putting "user" memories
+ // into low half of address space, and "system" into upper half.
+ // We're going to take advantage of that and return small int
+ // (signed) for such "user" addresses.
+ return MP_OBJ_NEW_SMALL_INT(id);
+ } else {
+ // If that didn't work, well, let's return long int, just as
+ // a (big) positve value, so it will never clash with the range
+ // of small int returned in previous case.
+ return mp_obj_new_int_from_uint((mp_uint_t)id);
+ }
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_id_obj, mp_builtin_id);
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 467a27897c..debf75fd4d 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -120,6 +120,9 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
// set the new context
mp_locals_set(mp_obj_module_get_globals(module_obj));
mp_globals_set(mp_obj_module_get_globals(module_obj));
+ #if MICROPY_PY___FILE__
+ mp_store_attr(module_obj, MP_QSTR___file__, mp_obj_new_str(vstr_str(file), vstr_len(file), false));
+ #endif
// parse the imported script
mp_parse_error_kind_t parse_error_kind;
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 911125c8a4..351910b6dd 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -289,6 +289,11 @@ typedef double mp_float_t;
#define MICROPY_PY_BUILTINS_PROPERTY (1)
#endif
+// Whether to set __file__ for imported modules
+#ifndef MICROPY_PY___FILE__
+#define MICROPY_PY___FILE__ (1)
+#endif
+
// Whether to provide "array" module. Note that large chunk of the
// underlying code is shared with "bytearray" builtin type, so to
// get real savings, it should be disabled too.
diff --git a/py/obj.h b/py/obj.h
index 5f347a2674..c391611c10 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -228,13 +228,14 @@ bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags);
void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags);
// Stream protocol
+#define MP_STREAM_ERROR (-1)
typedef struct _mp_stream_p_t {
- // On error, functions should return -1 and fill in *errcode (values are
- // implementation-dependent, but will be exposed to user, e.g. via exception).
- mp_int_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
- mp_int_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode);
+ // On error, functions should return MP_STREAM_ERROR and fill in *errcode (values
+ // are implementation-dependent, but will be exposed to user, e.g. via exception).
+ mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
+ mp_uint_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode);
// add seek() ?
- int is_bytes : 1;
+ int is_text : 1; // default is bytes, set this for text stream
} mp_stream_p_t;
struct _mp_obj_type_t {
diff --git a/py/objstringio.c b/py/objstringio.c
index bffdf2cf79..70f0c68dd4 100644
--- a/py/objstringio.c
+++ b/py/objstringio.c
@@ -51,7 +51,7 @@ STATIC void stringio_print(void (*print)(void *env, const char *fmt, ...), void
print(env, self->base.type == &mp_type_stringio ? "<io.StringIO 0x%x>" : "<io.BytesIO 0x%x>", self->vstr);
}
-STATIC mp_int_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
mp_obj_stringio_t *o = o_in;
mp_uint_t remaining = o->vstr->len - o->pos;
if (size > remaining) {
@@ -62,7 +62,7 @@ STATIC mp_int_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *err
return size;
}
-STATIC mp_int_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
mp_obj_stringio_t *o = o_in;
mp_uint_t remaining = o->vstr->alloc - o->pos;
if (size > remaining) {
@@ -137,12 +137,12 @@ STATIC MP_DEFINE_CONST_DICT(stringio_locals_dict, stringio_locals_dict_table);
STATIC const mp_stream_p_t stringio_stream_p = {
.read = stringio_read,
.write = stringio_write,
+ .is_text = true,
};
STATIC const mp_stream_p_t bytesio_stream_p = {
.read = stringio_read,
.write = stringio_write,
- .is_bytes = true,
};
const mp_obj_type_t mp_type_stringio = {
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index 25311479c3..6470cb9509 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -43,6 +43,9 @@ Q(__next__)
Q(__qualname__)
Q(__path__)
Q(__repl_print__)
+#if MICROPY_PY___FILE__
+Q(__file__)
+#endif
Q(__bool__)
Q(__contains__)
diff --git a/py/stream.c b/py/stream.c
index ad5855c706..09c39bdf4a 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -58,7 +58,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in);
#define is_nonblocking_error(errno) (0)
#endif
-#define STREAM_CONTENT_TYPE(stream) (((stream)->is_bytes) ? &mp_type_bytes : &mp_type_str)
+#define STREAM_CONTENT_TYPE(stream) (((stream)->is_text) ? &mp_type_str : &mp_type_bytes)
STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)args[0];
@@ -76,7 +76,7 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
}
#if MICROPY_PY_BUILTINS_STR_UNICODE
- if (!o->type->stream_p->is_bytes) {
+ if (o->type->stream_p->is_text) {
// We need to read sz number of unicode characters. Because we don't have any
// buffering, and because the stream API can only read bytes, we must read here
// in units of bytes and must never over read. If we want sz chars, then reading
@@ -96,8 +96,8 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, "out of memory"));
}
int error;
- mp_int_t out_sz = o->type->stream_p->read(o, p, more_bytes, &error);
- if (out_sz == -1) {
+ mp_uint_t out_sz = o->type->stream_p->read(o, p, more_bytes, &error);
+ if (out_sz == MP_STREAM_ERROR) {
vstr_cut_tail_bytes(&vstr, more_bytes);
if (is_nonblocking_error(error)) {
// With non-blocking streams, we read as much as we can.
@@ -113,7 +113,7 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
}
- if ((mp_uint_t)out_sz < more_bytes) {
+ if (out_sz < more_bytes) {
// Finish reading.
// TODO what if we have read only half a non-ASCII char?
vstr_cut_tail_bytes(&vstr, more_bytes - out_sz);
@@ -168,8 +168,8 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
byte *buf = m_new(byte, sz);
int error;
- mp_int_t out_sz = o->type->stream_p->read(o, buf, sz, &error);
- if (out_sz == -1) {
+ mp_uint_t out_sz = o->type->stream_p->read(o, buf, sz, &error);
+ if (out_sz == MP_STREAM_ERROR) {
if (is_nonblocking_error(error)) {
// https://docs.python.org/3.4/library/io.html#io.RawIOBase.read
// "If the object is in non-blocking mode and no bytes are available,
@@ -194,8 +194,8 @@ mp_obj_t mp_stream_write(mp_obj_t self_in, const void *buf, mp_uint_t len) {
}
int error;
- mp_int_t out_sz = o->type->stream_p->write(self_in, buf, len, &error);
- if (out_sz == -1) {
+ mp_uint_t out_sz = o->type->stream_p->write(self_in, buf, len, &error);
+ if (out_sz == MP_STREAM_ERROR) {
if (is_nonblocking_error(error)) {
// http://docs.python.org/3/library/io.html#io.RawIOBase.write
// "None is returned if the raw stream is set not to block and
@@ -230,8 +230,8 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
int error;
int current_read = DEFAULT_BUFFER_SIZE;
while (true) {
- mp_int_t out_sz = o->type->stream_p->read(self_in, p, current_read, &error);
- if (out_sz == -1) {
+ mp_uint_t out_sz = o->type->stream_p->read(self_in, p, current_read, &error);
+ if (out_sz == MP_STREAM_ERROR) {
if (is_nonblocking_error(error)) {
// With non-blocking streams, we read as much as we can.
// If we read nothing, return None, just like read().
@@ -292,16 +292,15 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, "out of memory"));
}
- mp_int_t out_sz = o->type->stream_p->read(o, p, 1, &error);
- if (out_sz == -1) {
+ mp_uint_t out_sz = o->type->stream_p->read(o, p, 1, &error);
+ if (out_sz == MP_STREAM_ERROR) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
}
if (out_sz == 0) {
// Back out previously added byte
- // TODO: This is a bit hacky, does it supported by vstr API contract?
// Consider, what's better - read a char and get OutOfMemory (so read
// char is lost), or allocate first as we do.
- vstr_add_len(vstr, -1);
+ vstr_cut_tail_bytes(vstr, 1);
break;
}
if (*p == '\n') {