|
| 1 | +// This file is part of the CircuitPython project: https://circuitpython.org |
| 2 | +// |
| 3 | +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries |
| 4 | +// |
| 5 | +// SPDX-License-Identifier: MIT |
| 6 | + |
| 7 | +#include <string.h> |
| 8 | + |
| 9 | +#include "py/obj.h" |
| 10 | +#include "py/objproperty.h" |
| 11 | +#include "py/runtime.h" |
| 12 | +#include "py/mperrno.h" |
| 13 | +#include "py/mphal.h" |
| 14 | +#include "py/gc.h" |
| 15 | +#include "py/objstr.h" |
| 16 | +#include "py/objtuple.h" |
| 17 | +#include "py/objtype.h" |
| 18 | + |
| 19 | +#include "shared-bindings/pathlib/PosixPath.h" |
| 20 | +#include "shared-module/pathlib/PosixPath.h" |
| 21 | + |
| 22 | +//| class PosixPath: |
| 23 | +//| """Object representing a path on Posix systems""" |
| 24 | +//| |
| 25 | +//| def __init__(self, path: Union[str, "PosixPath"]) -> None: |
| 26 | +//| """Construct a PosixPath object from a string or another PosixPath object. |
| 27 | +//| |
| 28 | +//| :param path: A string or PosixPath object representing a path |
| 29 | +//| """ |
| 30 | +//| ... |
| 31 | +//| |
| 32 | + |
| 33 | +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) { |
| 34 | + mp_arg_check_num(n_args, n_kw, 1, 1, false); |
| 35 | + return common_hal_pathlib_posixpath_new(args[0]); |
| 36 | +} |
| 37 | + |
| 38 | +//| def joinpath(self, *args: Union[str, "PosixPath"]) -> "PosixPath": |
| 39 | +//| """Join path components. |
| 40 | +//| |
| 41 | +//| :param args: Path components to join |
| 42 | +//| :return: A new PosixPath object |
| 43 | +//| """ |
| 44 | +//| ... |
| 45 | +//| |
| 46 | +//| def __truediv__(self, other: Union[str, "PosixPath"]) -> "PosixPath": |
| 47 | +//| """Implement path / other for joining paths. |
| 48 | +//| |
| 49 | +//| :param other: Path component to join |
| 50 | +//| :return: A new PosixPath object |
| 51 | +//| """ |
| 52 | +//| ... |
| 53 | +//| |
| 54 | + |
| 55 | +static mp_obj_t pathlib_posixpath_joinpath(mp_obj_t self_in, mp_obj_t arg) { |
| 56 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 57 | + return common_hal_pathlib_posixpath_joinpath(self, arg); |
| 58 | +} |
| 59 | +MP_DEFINE_CONST_FUN_OBJ_2(pathlib_posixpath_joinpath_obj, pathlib_posixpath_joinpath); |
| 60 | + |
| 61 | +// Binary operator for implementing the / operator |
| 62 | +static mp_obj_t pathlib_posixpath_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { |
| 63 | + switch (op) { |
| 64 | + case MP_BINARY_OP_TRUE_DIVIDE: { |
| 65 | + // Implement path / other |
| 66 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(lhs); |
| 67 | + return common_hal_pathlib_posixpath_joinpath(self, rhs); |
| 68 | + } |
| 69 | + default: |
| 70 | + return MP_OBJ_NULL; // op not supported |
| 71 | + } |
| 72 | +} |
| 73 | + |
| 74 | +//| @property |
| 75 | +//| def parent(self) -> "PosixPath": |
| 76 | +//| """The logical parent of the path.""" |
| 77 | +//| ... |
| 78 | +//| |
| 79 | + |
| 80 | +static mp_obj_t pathlib_posixpath_parent(mp_obj_t self_in) { |
| 81 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 82 | + return common_hal_pathlib_posixpath_parent(self); |
| 83 | +} |
| 84 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_parent_obj, pathlib_posixpath_parent); |
| 85 | + |
| 86 | +MP_PROPERTY_GETTER(pathlib_posixpath_parent_property_obj, |
| 87 | + (mp_obj_t)&pathlib_posixpath_parent_obj); |
| 88 | + |
| 89 | +//| @property |
| 90 | +//| def name(self) -> str: |
| 91 | +//| """The final path component, excluding the drive and root, if any.""" |
| 92 | +//| ... |
| 93 | +//| |
| 94 | + |
| 95 | +static mp_obj_t pathlib_posixpath_name(mp_obj_t self_in) { |
| 96 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 97 | + return common_hal_pathlib_posixpath_name(self); |
| 98 | +} |
| 99 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_name_obj, pathlib_posixpath_name); |
| 100 | + |
| 101 | +MP_PROPERTY_GETTER(pathlib_posixpath_name_property_obj, |
| 102 | + (mp_obj_t)&pathlib_posixpath_name_obj); |
| 103 | + |
| 104 | +//| @property |
| 105 | +//| def stem(self) -> str: |
| 106 | +//| """The final path component, without its suffix.""" |
| 107 | +//| ... |
| 108 | +//| |
| 109 | + |
| 110 | +static mp_obj_t pathlib_posixpath_stem(mp_obj_t self_in) { |
| 111 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 112 | + return common_hal_pathlib_posixpath_stem(self); |
| 113 | +} |
| 114 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_stem_obj, pathlib_posixpath_stem); |
| 115 | + |
| 116 | +MP_PROPERTY_GETTER(pathlib_posixpath_stem_property_obj, |
| 117 | + (mp_obj_t)&pathlib_posixpath_stem_obj); |
| 118 | + |
| 119 | +//| @property |
| 120 | +//| def suffix(self) -> str: |
| 121 | +//| """The final component's extension.""" |
| 122 | +//| ... |
| 123 | +//| |
| 124 | + |
| 125 | +static mp_obj_t pathlib_posixpath_suffix(mp_obj_t self_in) { |
| 126 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 127 | + return common_hal_pathlib_posixpath_suffix(self); |
| 128 | +} |
| 129 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_suffix_obj, pathlib_posixpath_suffix); |
| 130 | + |
| 131 | +MP_PROPERTY_GETTER(pathlib_posixpath_suffix_property_obj, |
| 132 | + (mp_obj_t)&pathlib_posixpath_suffix_obj); |
| 133 | + |
| 134 | +//| def exists(self) -> bool: |
| 135 | +//| """Check whether the path exists.""" |
| 136 | +//| ... |
| 137 | +//| |
| 138 | + |
| 139 | +static mp_obj_t pathlib_posixpath_exists(mp_obj_t self_in) { |
| 140 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 141 | + return common_hal_pathlib_posixpath_exists(self); |
| 142 | +} |
| 143 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_exists_obj, pathlib_posixpath_exists); |
| 144 | + |
| 145 | +//| def is_dir(self) -> bool: |
| 146 | +//| """Check whether the path is a directory.""" |
| 147 | +//| ... |
| 148 | +//| |
| 149 | + |
| 150 | +static mp_obj_t pathlib_posixpath_is_dir(mp_obj_t self_in) { |
| 151 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 152 | + return common_hal_pathlib_posixpath_is_dir(self); |
| 153 | +} |
| 154 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_is_dir_obj, pathlib_posixpath_is_dir); |
| 155 | + |
| 156 | +//| def is_file(self) -> bool: |
| 157 | +//| """Check whether the path is a regular file.""" |
| 158 | +//| ... |
| 159 | +//| |
| 160 | + |
| 161 | +static mp_obj_t pathlib_posixpath_is_file(mp_obj_t self_in) { |
| 162 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 163 | + return common_hal_pathlib_posixpath_is_file(self); |
| 164 | +} |
| 165 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_is_file_obj, pathlib_posixpath_is_file); |
| 166 | + |
| 167 | +//| def absolute(self) -> "PosixPath": |
| 168 | +//| """Return an absolute version of this path.""" |
| 169 | +//| ... |
| 170 | +//| |
| 171 | + |
| 172 | +static mp_obj_t pathlib_posixpath_absolute(mp_obj_t self_in) { |
| 173 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 174 | + return common_hal_pathlib_posixpath_absolute(self); |
| 175 | +} |
| 176 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_absolute_obj, pathlib_posixpath_absolute); |
| 177 | + |
| 178 | +//| def resolve(self) -> "PosixPath": |
| 179 | +//| """Make the path absolute, resolving any symlinks.""" |
| 180 | +//| ... |
| 181 | +//| |
| 182 | + |
| 183 | +static mp_obj_t pathlib_posixpath_resolve(mp_obj_t self_in) { |
| 184 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 185 | + return common_hal_pathlib_posixpath_resolve(self); |
| 186 | +} |
| 187 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_resolve_obj, pathlib_posixpath_resolve); |
| 188 | + |
| 189 | +//| def iterdir(self) -> Iterator["PosixPath"]: |
| 190 | +//| """Iterate over the files in this directory. |
| 191 | +//| Does not include the special paths '.' and '..'. |
| 192 | +//| |
| 193 | +//| :return: An iterator yielding path objects |
| 194 | +//| |
| 195 | +//| Example:: |
| 196 | +//| |
| 197 | +//| for path in Path('.').iterdir(): |
| 198 | +//| print(path) |
| 199 | +//| """ |
| 200 | +//| ... |
| 201 | +//| |
| 202 | + |
| 203 | +static mp_obj_t pathlib_posixpath_iterdir(mp_obj_t self_in) { |
| 204 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 205 | + return common_hal_pathlib_posixpath_iterdir(self); |
| 206 | +} |
| 207 | +MP_DEFINE_CONST_FUN_OBJ_1(pathlib_posixpath_iterdir_obj, pathlib_posixpath_iterdir); |
| 208 | + |
| 209 | +static const mp_rom_map_elem_t pathlib_posixpath_locals_dict_table[] = { |
| 210 | + { MP_ROM_QSTR(MP_QSTR_joinpath), MP_ROM_PTR(&pathlib_posixpath_joinpath_obj) }, |
| 211 | + { MP_ROM_QSTR(MP_QSTR_exists), MP_ROM_PTR(&pathlib_posixpath_exists_obj) }, |
| 212 | + { MP_ROM_QSTR(MP_QSTR_is_dir), MP_ROM_PTR(&pathlib_posixpath_is_dir_obj) }, |
| 213 | + { MP_ROM_QSTR(MP_QSTR_is_file), MP_ROM_PTR(&pathlib_posixpath_is_file_obj) }, |
| 214 | + { MP_ROM_QSTR(MP_QSTR_absolute), MP_ROM_PTR(&pathlib_posixpath_absolute_obj) }, |
| 215 | + { MP_ROM_QSTR(MP_QSTR_resolve), MP_ROM_PTR(&pathlib_posixpath_resolve_obj) }, |
| 216 | + { MP_ROM_QSTR(MP_QSTR_iterdir), MP_ROM_PTR(&pathlib_posixpath_iterdir_obj) }, |
| 217 | + |
| 218 | + // Properties |
| 219 | + { MP_ROM_QSTR(MP_QSTR_parent), MP_ROM_PTR(&pathlib_posixpath_parent_property_obj) }, |
| 220 | + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&pathlib_posixpath_name_property_obj) }, |
| 221 | + { MP_ROM_QSTR(MP_QSTR_stem), MP_ROM_PTR(&pathlib_posixpath_stem_property_obj) }, |
| 222 | + { MP_ROM_QSTR(MP_QSTR_suffix), MP_ROM_PTR(&pathlib_posixpath_suffix_property_obj) }, |
| 223 | +}; |
| 224 | + |
| 225 | +static MP_DEFINE_CONST_DICT(pathlib_posixpath_locals_dict, pathlib_posixpath_locals_dict_table); |
| 226 | + |
| 227 | +// String representation for PosixPath objects |
| 228 | +static void pathlib_posixpath_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { |
| 229 | + pathlib_posixpath_obj_t *self = MP_OBJ_TO_PTR(self_in); |
| 230 | + // Just print the path string directly |
| 231 | + mp_obj_print_helper(print, self->path_str, kind); |
| 232 | +} |
| 233 | + |
| 234 | +MP_DEFINE_CONST_OBJ_TYPE( |
| 235 | + pathlib_posixpath_type, |
| 236 | + MP_QSTR_PosixPath, |
| 237 | + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, |
| 238 | + make_new, pathlib_posixpath_make_new, |
| 239 | + print, pathlib_posixpath_print, |
| 240 | + binary_op, pathlib_posixpath_binary_op, |
| 241 | + locals_dict, &pathlib_posixpath_locals_dict |
| 242 | + ); |
0 commit comments