Skip to content
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

[stdlib] tempfile and tempdir #2352

Closed
12 changes: 11 additions & 1 deletion stdlib/src/os/__init__.mojo
Expand Up @@ -15,5 +15,15 @@
from .atomic import Atomic
from .env import setenv, getenv
from .fstat import lstat, stat, stat_result
from .os import abort, listdir, remove, unlink, SEEK_SET, SEEK_CUR, SEEK_END
from .os import (
abort,
listdir,
remove,
unlink,
SEEK_SET,
SEEK_CUR,
SEEK_END,
mkdir,
rmdir,
)
from .pathlike import PathLike
59 changes: 58 additions & 1 deletion stdlib/src/os/os.mojo
Expand Up @@ -277,7 +277,7 @@ fn remove(path: String) raises:
path: The path to the file.

"""
var error = external_call["unlink", Int](path._as_ptr())
var error = external_call["unlink", Int32](path._as_ptr())

if error != 0:
# TODO get error message, the following code prints it
Expand Down Expand Up @@ -327,3 +327,60 @@ fn unlink[pathlike: os.PathLike](path: pathlike) raises:

"""
remove(path.__fspath__())


# ===----------------------------------------------------------------------=== #
# mkdir/rmdir
# ===----------------------------------------------------------------------=== #


fn mkdir(path: String, mode: Int = 0o777) raises:
"""Creates a directory at the specified path.
If the directory can not be created an error is raised.
Absolute and relative paths are allowed, relative paths are resolved from cwd.

Args:
path: The path to the directory.
mode: The mode to create the directory with.
"""

var error = external_call["mkdir", Int32](path._as_ptr(), mode)
if error != 0:
raise Error("Can not create directory: " + path)


fn mkdir[pathlike: os.PathLike](path: pathlike, mode: Int = 0o777) raises:
"""Creates a directory at the specified path.
If the directory can not be created an error is raised.
Absolute and relative paths are allowed, relative paths are resolved from cwd.

Args:
path: The path to the directory.
mode: The mode to create the directory with.
"""

mkdir(path.__fspath__(), mode)


fn rmdir(path: String) raises:
"""Removes the specified directory.
If the path is not a directory or it can not be deleted, an error is raised.
Absolute and relative paths are allowed, relative paths are resolved from cwd.

Args:
path: The path to the directory.
"""
var error = external_call["rmdir", Int32](path._as_ptr())
if error != 0:
raise Error("Can not remove directory: " + path)


fn rmdir[pathlike: os.PathLike](path: pathlike) raises:
"""Removes the specified directory.
If the path is not a directory or it can not be deleted, an error is raised.
Absolute and relative paths are allowed, relative paths are resolved from cwd.

Args:
path: The path to the directory.
"""
rmdir(path.__fspath__())
15 changes: 15 additions & 0 deletions stdlib/src/shutil/__init__.mojo
@@ -0,0 +1,15 @@
# ===----------------------------------------------------------------------=== #
# Copyright (c) 2024, Modular Inc. All rights reserved.
#
# Licensed under the Apache License v2.0 with LLVM Exceptions:
# https://llvm.org/LICENSE.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ===----------------------------------------------------------------------=== #
"""Implements the shutil package."""

from .shutil import rmtree
71 changes: 71 additions & 0 deletions stdlib/src/shutil/shutil.mojo
@@ -0,0 +1,71 @@
# ===----------------------------------------------------------------------=== #
# Copyright (c) 2024, Modular Inc. All rights reserved.
#
# Licensed under the Apache License v2.0 with LLVM Exceptions:
# https://llvm.org/LICENSE.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ===----------------------------------------------------------------------=== #
"""Implements a number of high-level operations on files and
collections of files.

You can import these APIs from the `shutil` package. For example:

```mojo
from shutil import rmtree
```
"""

from os import listdir
from os.path import islink, isdir, isfile


fn rmtree(path: String, ignore_errors: Bool = False) raises:
"""Removes the specified directory and all its contents.
If the path is a symbolic link, an error is raised.
If ignore_errors is True, errors resulting from failed removals will be ignored.
Absolute and relative paths are allowed, relative paths are resolved from cwd.

Args:
path: The path to the directory.
ignore_errors: Whether to ignore errors.
"""
if os.path.islink(path):
raise Error("`path`can not be a symbolic link")

for file_or_dir in listdir(path):
if isfile(path + "/" + file_or_dir[]):
try:
os.remove(path + "/" + file_or_dir[])
except e:
if not ignore_errors:
raise Error(e)
continue
if isdir(path + "/" + file_or_dir[]):
try:
rmtree(path + "/" + file_or_dir[], ignore_errors)
except e:
if ignore_errors:
continue
raise Error(e)

os.rmdir(path)


fn rmtree[
pathlike: os.PathLike
](path: pathlike, ignore_errors: Bool = False) raises:
"""Removes the specified directory and all its contents.
If the path is a symbolic link, an error is raised.
If ignore_errors is True, errors resulting from failed removals will be ignored.
Absolute and relative paths are allowed, relative paths are resolved from cwd.

Args:
path: The path to the directory.
ignore_errors: Whether to ignore errors.
"""
rmtree(path.__fspath__(), ignore_errors)
15 changes: 15 additions & 0 deletions stdlib/src/tempfile/__init__.mojo
@@ -0,0 +1,15 @@
# ===----------------------------------------------------------------------=== #
# Copyright (c) 2024, Modular Inc. All rights reserved.
#
# Licensed under the Apache License v2.0 with LLVM Exceptions:
# https://llvm.org/LICENSE.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ===----------------------------------------------------------------------=== #
"""Implements the tempfile package."""

from .tempfile import NamedTemporaryFile, TemporaryDirectory