Skip to content

parse tuple from os_stat for dir/file methods #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
[submodule "ports/raspberrypi/sdk"]
path = ports/raspberrypi/sdk
url = https://github.com/adafruit/pico-sdk.git
branch = force_inline_critical_section
branch = force_inline_critical_section_2.1.1
[submodule "data/nvm.toml"]
path = data/nvm.toml
url = https://github.com/adafruit/nvm.toml.git
Expand Down
4 changes: 4 additions & 0 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -3024,6 +3024,10 @@ msgstr ""
msgid "expected ':' after format specifier"
msgstr ""

#: shared-module/pathlib/PosixPath.c
msgid "expected str or PosixPath"
msgstr ""

#: py/obj.c
msgid "expected tuple/list"
msgstr ""
Expand Down
10 changes: 6 additions & 4 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,14 +457,19 @@ static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *s
usb_setup_with_vm();
#endif

// Always return to root before trying to run files.
common_hal_os_chdir("/");
// Check if a different run file has been allocated
if (next_code_configuration != NULL) {
next_code_configuration->options &= ~SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET;
next_code_options = next_code_configuration->options;
if (next_code_configuration->filename[0] != '\0') {
if (next_code_configuration->working_directory != NULL) {
common_hal_os_chdir(next_code_configuration->working_directory);
}
// This is where the user's python code is actually executed:
const char *const filenames[] = { next_code_configuration->filename };
found_main = maybe_run_list(filenames, MP_ARRAY_SIZE(filenames));
found_main = maybe_run_list(filenames, 1);
if (!found_main) {
serial_write(next_code_configuration->filename);
serial_write_compressed(MP_ERROR_TEXT(" not found.\n"));
Expand Down Expand Up @@ -1109,9 +1114,6 @@ int __attribute__((used)) main(void) {
}
simulate_reset = false;

// Always return to root before trying to run files.
common_hal_os_chdir("/");

if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
// If code.py did a fake deep sleep, pretend that we
// are running code.py for the first time after a hard
Expand Down
5 changes: 5 additions & 0 deletions py/circuitpy_defns.mk
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ endif
ifeq ($(CIRCUITPY_OS),1)
SRC_PATTERNS += os/%
endif
ifeq ($(CIRCUITPY_PATHLIB),1)
SRC_PATTERNS += pathlib/%
endif
ifeq ($(CIRCUITPY_DUALBANK),1)
SRC_PATTERNS += dualbank/%
endif
Expand Down Expand Up @@ -714,6 +717,8 @@ SRC_SHARED_MODULE_ALL = \
onewireio/__init__.c \
onewireio/OneWire.c \
os/__init__.c \
pathlib/__init__.c \
pathlib/PosixPath.c \
paralleldisplaybus/ParallelBus.c \
qrio/__init__.c \
qrio/QRDecoder.c \
Expand Down
3 changes: 3 additions & 0 deletions py/circuitpy_mpconfig.mk
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,9 @@ CFLAGS += -DCIRCUITPY_OPT_MAP_LOOKUP_CACHE=$(CIRCUITPY_OPT_MAP_LOOKUP_CACHE)
CIRCUITPY_OS ?= 1
CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS)

CIRCUITPY_PATHLIB ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_PATHLIB=$(CIRCUITPY_PATHLIB)

CIRCUITPY_PEW ?= 0
CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)

Expand Down
236 changes: 236 additions & 0 deletions shared-bindings/pathlib/PosixPath.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
#include <string.h>

#include "py/obj.h"
#include "py/objproperty.h"
#include "py/runtime.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "py/gc.h"
#include "py/objstr.h"
#include "py/objtuple.h"
#include "py/objtype.h"

#include "shared-bindings/pathlib/PosixPath.h"
#include "shared-module/pathlib/PosixPath.h"

//| class PosixPath:
//| """Object representing a path on Posix systems"""
//|
//| def __init__(self, path: Union[str, "PosixPath"]) -> None:
//| """Construct a PosixPath object from a string or another PosixPath object.
//|
//| :param path: A string or PosixPath object representing a path
//| """
//| ...
//|

static mp_obj_t pathlib_posixpath_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 1, false);
return common_hal_pathlib_posixpath_new(args[0]);
}

//| def joinpath(self, *args: Union[str, "PosixPath"]) -> "PosixPath":
//| """Join path components.
//|
//| :param args: Path components to join
//| :return: A new PosixPath object
//| """
//| ...
//|
//| def __truediv__(self, other: Union[str, "PosixPath"]) -> "PosixPath":
//| """Implement path / other for joining paths.
//|
//| :param other: Path component to join
//| :return: A new PosixPath object
//| """
//| ...
//|

static mp_obj_t pathlib_posixpath_joinpath(mp_obj_t self_in, mp_obj_t arg) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_joinpath(self, arg);
}
MP_DEFINE_CONST_FUN_OBJ_2(pathlib_posixpath_joinpath_obj, pathlib_posixpath_joinpath);

// Binary operator for implementing the / operator
static mp_obj_t pathlib_posixpath_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
switch (op) {
case MP_BINARY_OP_TRUE_DIVIDE: {
// Implement path / other
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(lhs);
return common_hal_pathlib_posixpath_joinpath(self, rhs);
}
default:
return MP_OBJ_NULL; // op not supported
}
}

//| @property
//| def parent(self) -> "PosixPath":
//| """The logical parent of the path."""
//| ...
//|

static mp_obj_t pathlib_posixpath_parent(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_parent(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_parent_obj, pathlib_posixpath_parent);

MP_PROPERTY_GETTER(pathlib_posixpath_parent_property_obj,
(mp_obj_t)&pathlib_posixpath_parent_obj);

//| @property
//| def name(self) -> str:
//| """The final path component, excluding the drive and root, if any."""
//| ...
//|

static mp_obj_t pathlib_posixpath_name(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_name(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_name_obj, pathlib_posixpath_name);

MP_PROPERTY_GETTER(pathlib_posixpath_name_property_obj,
(mp_obj_t)&pathlib_posixpath_name_obj);

//| @property
//| def stem(self) -> str:
//| """The final path component, without its suffix."""
//| ...
//|

static mp_obj_t pathlib_posixpath_stem(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_stem(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_stem_obj, pathlib_posixpath_stem);

MP_PROPERTY_GETTER(pathlib_posixpath_stem_property_obj,
(mp_obj_t)&pathlib_posixpath_stem_obj);

//| @property
//| def suffix(self) -> str:
//| """The final component's extension."""
//| ...
//|

static mp_obj_t pathlib_posixpath_suffix(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_suffix(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_suffix_obj, pathlib_posixpath_suffix);

MP_PROPERTY_GETTER(pathlib_posixpath_suffix_property_obj,
(mp_obj_t)&pathlib_posixpath_suffix_obj);

//| def exists(self) -> bool:
//| """Check whether the path exists."""
//| ...
//|

static mp_obj_t pathlib_posixpath_exists(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_exists(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_exists_obj, pathlib_posixpath_exists);

//| def is_dir(self) -> bool:
//| """Check whether the path is a directory."""
//| ...
//|

static mp_obj_t pathlib_posixpath_is_dir(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_is_dir(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_is_dir_obj, pathlib_posixpath_is_dir);

//| def is_file(self) -> bool:
//| """Check whether the path is a regular file."""
//| ...
//|

static mp_obj_t pathlib_posixpath_is_file(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_is_file(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_is_file_obj, pathlib_posixpath_is_file);

//| def absolute(self) -> "PosixPath":
//| """Return an absolute version of this path."""
//| ...
//|

static mp_obj_t pathlib_posixpath_absolute(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_absolute(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_absolute_obj, pathlib_posixpath_absolute);

//| def resolve(self) -> "PosixPath":
//| """Make the path absolute, resolving any symlinks."""
//| ...
//|

static mp_obj_t pathlib_posixpath_resolve(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_resolve(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_resolve_obj, pathlib_posixpath_resolve);

//| def iterdir(self) -> Iterator["PosixPath"]:
//| """Iterate over the files in this directory.
//| Does not include the special paths '.' and '..'.
//|
//| :return: An iterator yielding path objects
//|
//| Example::
//|
//| for path in Path('.').iterdir():
//| print(path)
//| """
//| ...
//|

static mp_obj_t pathlib_posixpath_iterdir(mp_obj_t self_in) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_pathlib_posixpath_iterdir(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_iterdir_obj, pathlib_posixpath_iterdir);

static const mp_rom_map_elem_t pathlib_posixpath_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_joinpath), MP_ROM_PTR(&pathlib_posixpath_joinpath_obj) },
{ MP_ROM_QSTR(MP_QSTR_exists), MP_ROM_PTR(&pathlib_posixpath_exists_obj) },
{ MP_ROM_QSTR(MP_QSTR_is_dir), MP_ROM_PTR(&pathlib_posixpath_is_dir_obj) },
{ MP_ROM_QSTR(MP_QSTR_is_file), MP_ROM_PTR(&pathlib_posixpath_is_file_obj) },
{ MP_ROM_QSTR(MP_QSTR_absolute), MP_ROM_PTR(&pathlib_posixpath_absolute_obj) },
{ MP_ROM_QSTR(MP_QSTR_resolve), MP_ROM_PTR(&pathlib_posixpath_resolve_obj) },
{ MP_ROM_QSTR(MP_QSTR_iterdir), MP_ROM_PTR(&pathlib_posixpath_iterdir_obj) },

// Properties
{ MP_ROM_QSTR(MP_QSTR_parent), MP_ROM_PTR(&pathlib_posixpath_parent_property_obj) },
{ MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&pathlib_posixpath_name_property_obj) },
{ MP_ROM_QSTR(MP_QSTR_stem), MP_ROM_PTR(&pathlib_posixpath_stem_property_obj) },
{ MP_ROM_QSTR(MP_QSTR_suffix), MP_ROM_PTR(&pathlib_posixpath_suffix_property_obj) },
};

static MP_DEFINE_CONST_DICT(pathlib_posixpath_locals_dict, pathlib_posixpath_locals_dict_table);

// String representation for PosixPath objects
static void pathlib_posixpath_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in);
// Just print the path string directly
mp_obj_print_helper(print, self->path_str, kind);
}

MP_DEFINE_CONST_OBJ_TYPE(
pathlib_posixpath_type,
MP_QSTR_PosixPath,
MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS,
make_new, pathlib_posixpath_make_new,
print, pathlib_posixpath_print,
binary_op, pathlib_posixpath_binary_op,
locals_dict, &pathlib_posixpath_locals_dict
);
21 changes: 21 additions & 0 deletions shared-bindings/pathlib/PosixPath.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "py/obj.h"

extern const mp_obj_type_t pathlib_posixpath_type;

// Include the struct definition from shared-module
#include "shared-module/pathlib/PosixPath.h"

mp_obj_t common_hal_pathlib_posixpath_new(mp_obj_t path);
mp_obj_t common_hal_pathlib_posixpath_joinpath(pathlib_posixpath_obj_t *self, mp_obj_t arg);
mp_obj_t common_hal_pathlib_posixpath_parent(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_name(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_stem(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_suffix(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_exists(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_is_dir(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_is_file(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_absolute(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_resolve(pathlib_posixpath_obj_t *self);
mp_obj_t common_hal_pathlib_posixpath_iterdir(pathlib_posixpath_obj_t *self);
40 changes: 40 additions & 0 deletions shared-bindings/pathlib/__init__.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <string.h>

#include "py/obj.h"
#include "py/runtime.h"
#include "py/objtype.h"

#include "shared-bindings/pathlib/__init__.h"
#include "shared-bindings/pathlib/PosixPath.h"

//| """Filesystem path operations"""
//|

//| class Path:
//| """Factory function that returns a new PosixPath."""
//|
//| def __new__(cls, *args) -> PosixPath:
//| """Create a new Path object.
//|
//| :param args: Path components
//| :return: A new PosixPath object
//| """
//| ...
//|

/* Path is just an alias for PosixPath in CircuitPython */

static const mp_rom_map_elem_t pathlib_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pathlib) },
{ MP_ROM_QSTR(MP_QSTR_Path), MP_ROM_PTR(&pathlib_posixpath_type) },
{ MP_ROM_QSTR(MP_QSTR_PosixPath), MP_ROM_PTR(&pathlib_posixpath_type) },
};

static MP_DEFINE_CONST_DICT(pathlib_module_globals, pathlib_module_globals_table);

const mp_obj_module_t pathlib_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&pathlib_module_globals,
};

MP_REGISTER_MODULE(MP_QSTR_pathlib, pathlib_module);
5 changes: 5 additions & 0 deletions shared-bindings/pathlib/__init__.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "py/obj.h"

mp_obj_t common_hal_pathlib_path_new(size_t n_args, const mp_obj_t *args);
Loading