From c93d43d7e3b0d01e4aeafbb961196517b89f9196 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 04:17:45 +0000 Subject: [PATCH 1/3] feat(stdlib): add pathlib module bindings with 36 tests Adds F# bindings for Python's pathlib.Path class: - Path construction (single string and multi-segment) - Properties: name, stem, suffix, suffixes, parent, parents, parts, root, anchor, drive - Path arithmetic: / operator (string and Path), joinpath - Pure transformations: with_name, with_stem, with_suffix, as_posix, as_uri - I/O predicates: exists, is_file, is_dir, is_symlink, is_mount, is_absolute - I/O operations: resolve, relative_to, read_text, read_bytes, write_text, write_bytes - Directory operations: mkdir, mkdir_p, rmdir, iterdir, glob, rglob - File operations: unlink, rename, replace, expanduser - Static factories: Path.cwd, Path.home - is_relative_to (3.9+) Includes 36 tests covering construction, properties, path arithmetic, transformations, predicates, file round-trips, and directory operations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Fable.Python.fsproj | 1 + src/stdlib/Pathlib.fs | 262 ++++++++++++++++++++++++++++++++++ test/Fable.Python.Test.fsproj | 1 + test/TestPathlib.fs | 242 +++++++++++++++++++++++++++++++ 4 files changed, 506 insertions(+) create mode 100644 src/stdlib/Pathlib.fs create mode 100644 test/TestPathlib.fs diff --git a/src/Fable.Python.fsproj b/src/Fable.Python.fsproj index 3dff498..e15d3a2 100644 --- a/src/Fable.Python.fsproj +++ b/src/Fable.Python.fsproj @@ -27,6 +27,7 @@ + diff --git a/src/stdlib/Pathlib.fs b/src/stdlib/Pathlib.fs new file mode 100644 index 0000000..476cb6d --- /dev/null +++ b/src/stdlib/Pathlib.fs @@ -0,0 +1,262 @@ +/// Type bindings for Python pathlib module: https://docs.python.org/3/library/pathlib.html +module Fable.Python.Pathlib + +open System +open Fable.Core + +// fsharplint:disable MemberNames + +/// Represents a filesystem path on the current OS (POSIX or Windows). +/// Paths are immutable; operations return new Path instances. +/// See https://docs.python.org/3/library/pathlib.html#pathlib.Path +[] +type Path(path: string) = + /// Construct a Path by joining multiple path segments. + /// Equivalent to Path(parts[0]) / parts[1] / … + [] + new([] paths: string[]) = Path("") + + // ------------------------------------------------------------------------- + // Properties + // ------------------------------------------------------------------------- + + /// The final path component (file or directory name). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.name + member _.name: string = nativeOnly + + /// The final path component without its last suffix (file extension). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.stem + member _.stem: string = nativeOnly + + /// The last file extension of the final component (e.g. ".py"), or "" if none. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.suffix + member _.suffix: string = nativeOnly + + /// All file extensions of the final component (e.g. [".tar"; ".gz"]). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.suffixes + member _.suffixes: ResizeArray = nativeOnly + + /// The logical parent of the path (directory containing this path). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parent + member _.parent: Path = nativeOnly + + /// Immutable sequence of the logical ancestors of the path. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parents + member _.parents: ResizeArray = nativeOnly + + /// The path's components as a tuple of strings. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parts + member _.parts: ResizeArray = nativeOnly + + /// The root component of the path (e.g. "/" on POSIX), or "". + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.root + member _.root: string = nativeOnly + + /// The concatenation of drive and root (e.g. "/" or "C:\\"), or "". + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.anchor + member _.anchor: string = nativeOnly + + /// The drive letter or name (relevant on Windows), or "". + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.drive + member _.drive: string = nativeOnly + + // ------------------------------------------------------------------------- + // Path arithmetic + // ------------------------------------------------------------------------- + + /// Return a new Path by appending a child string segment. + /// This mirrors Python's ``path / "child"`` operator. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.__truediv__ + [] + static member (/) (left: Path, right: string) : Path = nativeOnly + + /// Return a new Path by appending another Path. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.__truediv__ + [] + static member (/) (left: Path, right: Path) : Path = nativeOnly + + /// Join one or more path segments to this path and return the result. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.joinpath + [] + member _.joinpath([] parts: string[]) : Path = nativeOnly + + // ------------------------------------------------------------------------- + // Tests (pure — no I/O) + // ------------------------------------------------------------------------- + + /// Return True if the path is absolute (has both a root and, if applicable, a drive). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.is_absolute + member _.is_absolute() : bool = nativeOnly + + /// Return True if this path is relative to other (3.9+). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.is_relative_to + member _.is_relative_to(other: Path) : bool = nativeOnly + + /// Return True if this path is relative to the string path other (3.9+). + [] + member _.is_relative_to(other: string) : bool = nativeOnly + + // ------------------------------------------------------------------------- + // Transformations (pure — no I/O) + // ------------------------------------------------------------------------- + + /// Return a new path with the name component replaced. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.with_name + member _.with_name(name: string) : Path = nativeOnly + + /// Return a new path with the stem component replaced (3.9+). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.with_stem + member _.with_stem(stem: string) : Path = nativeOnly + + /// Return a new path with the suffix component replaced. + /// Pass "" to remove the suffix. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.with_suffix + member _.with_suffix(suffix: string) : Path = nativeOnly + + /// Return a string representation of the path. + /// Equivalent to Python's ``str(path)``. + [] + member _.str() : string = nativeOnly + + /// Return the path as a POSIX string (forward slashes). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.as_posix + member _.as_posix() : string = nativeOnly + + /// Return the path as a URI (file:// scheme). Only absolute paths are supported. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.as_uri + member _.as_uri() : string = nativeOnly + + // ------------------------------------------------------------------------- + // I/O queries + // ------------------------------------------------------------------------- + + /// Return True if the path points to an existing filesystem entry. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.exists + member _.exists() : bool = nativeOnly + + /// Return True if the path points to a regular file (follows symlinks). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_file + member _.is_file() : bool = nativeOnly + + /// Return True if the path points to a directory (follows symlinks). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_dir + member _.is_dir() : bool = nativeOnly + + /// Return True if the path points to a symbolic link. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_symlink + member _.is_symlink() : bool = nativeOnly + + /// Return True if the path is a mount point. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_mount + member _.is_mount() : bool = nativeOnly + + // ------------------------------------------------------------------------- + // I/O operations + // ------------------------------------------------------------------------- + + /// Make the path absolute and resolve any symlinks or ``..`` components. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve + member _.resolve() : Path = nativeOnly + + /// Make the path relative to other, raising ValueError if impossible. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.relative_to + member _.relative_to(other: Path) : Path = nativeOnly + + /// Make the path relative to a string path. + [] + member _.relative_to(other: string) : Path = nativeOnly + + /// Return the decoded contents of the file as a string (UTF-8 by default). + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.read_text + member _.read_text() : string = nativeOnly + + /// Return the decoded contents of the file using the given encoding. + [] + member _.read_text(encoding: string) : string = nativeOnly + + /// Return the binary contents of the file as a bytes object. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.read_bytes + member _.read_bytes() : byte[] = nativeOnly + + /// Write a string to the file, returning the number of characters written. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.write_text + [] + member _.write_text(data: string) : int = nativeOnly + + /// Write a string to the file with the given encoding. + [] + member _.write_text(data: string, encoding: string) : int = nativeOnly + + /// Write binary data to the file, returning the number of bytes written. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.write_bytes + member _.write_bytes(data: byte[]) : int = nativeOnly + + /// Iterate over the directory contents, yielding Path objects. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.iterdir + member _.iterdir() : Path seq = nativeOnly + + /// Glob the given relative pattern in the directory, returning matching paths. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob + member _.glob(pattern: string) : Path seq = nativeOnly + + /// Like glob() but descends into sub-directories recursively. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.rglob + member _.rglob(pattern: string) : Path seq = nativeOnly + + /// Create this directory. Raises FileExistsError if it already exists. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.mkdir + member _.mkdir() : unit = nativeOnly + + /// Create this directory with options. + /// parents=true creates any missing parent directories. + /// exist_ok=true suppresses FileExistsError. + [] + member _.mkdir(mode: int, parents: bool, exist_ok: bool) : unit = nativeOnly + + /// Create this directory and all missing parents (equivalent to ``mkdir -p``). + [] + member _.mkdir_p() : unit = nativeOnly + + /// Remove this directory. The directory must be empty. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.rmdir + member _.rmdir() : unit = nativeOnly + + /// Remove this file (or symbolic link). Raises FileNotFoundError if missing. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.unlink + member _.unlink() : unit = nativeOnly + + /// Remove this file; if missing_ok is true, no error is raised. + [] + member _.unlink(missing_ok: bool) : unit = nativeOnly + + /// Rename the file or directory to target, returning the new Path. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.rename + member _.rename(target: Path) : Path = nativeOnly + + /// Rename the file or directory to a string target, returning the new Path. + [] + member _.rename(target: string) : Path = nativeOnly + + /// Rename to target, overwriting any existing destination. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.replace + member _.replace(target: Path) : Path = nativeOnly + + /// Rename to a string target, overwriting any existing destination. + [] + member _.replace(target: string) : Path = nativeOnly + + /// Expand the ``~`` user home directory shortcut. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.expanduser + member _.expanduser() : Path = nativeOnly + + // ------------------------------------------------------------------------- + // Static factory methods + // ------------------------------------------------------------------------- + + /// Return a new Path representing the current working directory. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.cwd + static member cwd() : Path = nativeOnly + + /// Return a new Path representing the user's home directory. + /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path.home + static member home() : Path = nativeOnly diff --git a/test/Fable.Python.Test.fsproj b/test/Fable.Python.Test.fsproj index 441f8a7..423d846 100644 --- a/test/Fable.Python.Test.fsproj +++ b/test/Fable.Python.Test.fsproj @@ -33,6 +33,7 @@ + diff --git a/test/TestPathlib.fs b/test/TestPathlib.fs new file mode 100644 index 0000000..ca4cad9 --- /dev/null +++ b/test/TestPathlib.fs @@ -0,0 +1,242 @@ +module Fable.Python.Tests.Pathlib + +open Fable.Python.Testing +open Fable.Python.Pathlib + +// ============================================================================ +// Construction +// ============================================================================ + +[] +let ``test Path construction from string`` () = + let p = Path "/tmp" + p.str () |> equal "/tmp" + +[] +let ``test Path cwd returns absolute path`` () = + let p = Path.cwd () + p.is_absolute () |> equal true + +[] +let ``test Path home returns absolute path`` () = + let p = Path.home () + p.is_absolute () |> equal true + +// ============================================================================ +// Properties +// ============================================================================ + +[] +let ``test Path name`` () = + let p = Path "/foo/bar/baz.txt" + p.name |> equal "baz.txt" + +[] +let ``test Path stem`` () = + let p = Path "/foo/bar/baz.txt" + p.stem |> equal "baz" + +[] +let ``test Path suffix`` () = + let p = Path "/foo/bar/baz.txt" + p.suffix |> equal ".txt" + +[] +let ``test Path suffix absent`` () = + let p = Path "/foo/bar/README" + p.suffix |> equal "" + +[] +let ``test Path suffixes multiple`` () = + let p = Path "/foo/bar/archive.tar.gz" + p.suffixes |> Seq.toList |> equal [ ".tar"; ".gz" ] + +[] +let ``test Path parent`` () = + let p = Path "/foo/bar/baz.txt" + p.parent.str () |> equal "/foo/bar" + +[] +let ``test Path root on absolute path`` () = + let p = Path "/foo/bar" + p.root |> equal "/" + +[] +let ``test Path anchor`` () = + let p = Path "/foo/bar" + p.anchor |> equal "/" + +// ============================================================================ +// Path arithmetic +// ============================================================================ + +[] +let ``test Path slash operator with string`` () = + let p = Path "/foo" / "bar" + p.str () |> equal "/foo/bar" + +[] +let ``test Path slash operator chained`` () = + let p = Path "/foo" / "bar" / "baz" + p.str () |> equal "/foo/bar/baz" + +[] +let ``test Path slash operator with Path`` () = + let base' = Path "/foo" + let child = Path "bar" + let p = base' / child + p.str () |> equal "/foo/bar" + +[] +let ``test Path joinpath`` () = + let p = Path("/foo").joinpath ("bar", "baz") + p.str () |> equal "/foo/bar/baz" + +// ============================================================================ +// Transformations (pure) +// ============================================================================ + +[] +let ``test Path with_name`` () = + let p = Path "/foo/bar/baz.txt" + p.with_name("qux.txt").str () |> equal "/foo/bar/qux.txt" + +[] +let ``test Path with_stem`` () = + let p = Path "/foo/bar/baz.txt" + p.with_stem("qux").str () |> equal "/foo/bar/qux.txt" + +[] +let ``test Path with_suffix`` () = + let p = Path "/foo/bar/baz.txt" + p.with_suffix(".py").str () |> equal "/foo/bar/baz.py" + +[] +let ``test Path with_suffix empty removes extension`` () = + let p = Path "/foo/bar/baz.txt" + p.with_suffix("").str () |> equal "/foo/bar/baz" + +[] +let ``test Path as_posix`` () = + let p = Path "/foo/bar/baz.txt" + p.as_posix () |> equal "/foo/bar/baz.txt" + +// ============================================================================ +// is_* predicates +// ============================================================================ + +[] +let ``test Path is_absolute true`` () = + let p = Path "/foo/bar" + p.is_absolute () |> equal true + +[] +let ``test Path is_absolute false`` () = + let p = Path "foo/bar" + p.is_absolute () |> equal false + +[] +let ``test Path is_relative_to`` () = + let p = Path "/foo/bar/baz" + p.is_relative_to (Path "/foo") |> equal true + +[] +let ``test Path is_relative_to string`` () = + let p = Path "/foo/bar/baz" + p.is_relative_to "/foo" |> equal true + +[] +let ``test Path is_relative_to false`` () = + let p = Path "/foo/bar" + p.is_relative_to (Path "/baz") |> equal false + +// ============================================================================ +// I/O queries on a real temp file +// ============================================================================ + +[] +let ``test Path exists true for cwd`` () = + Path.cwd().exists () |> equal true + +[] +let ``test Path exists false for nonexistent`` () = + let p = Path "/nonexistent_repo_assist_xyz" + p.exists () |> equal false + +[] +let ``test Path is_dir true for cwd`` () = + Path.cwd().is_dir () |> equal true + +[] +let ``test Path is_file false for cwd`` () = + Path.cwd().is_file () |> equal false + +[] +let ``test Path resolve returns absolute`` () = + let p = Path "." + p.resolve().is_absolute () |> equal true + +[] +let ``test Path relative_to`` () = + let p = Path "/foo/bar/baz" + p.relative_to(Path "/foo/bar").str () |> equal "baz" + +[] +let ``test Path relative_to string`` () = + let p = Path "/foo/bar/baz" + p.relative_to("/foo/bar").str () |> equal "baz" + +// ============================================================================ +// File round-trip: write_text / read_text / unlink +// ============================================================================ + +[] +let ``test Path write_text and read_text`` () = + let tmp = Path.cwd () / "__pathlib_test_write__.txt" + tmp.write_text "hello pathlib" |> ignore + let content = tmp.read_text () + tmp.unlink (missing_ok = true) + content |> equal "hello pathlib" + +[] +let ``test Path write_bytes and read_bytes`` () = + let tmp = Path.cwd () / "__pathlib_test_bytes__.bin" + let data: byte[] = [| 0uy; 1uy; 2uy; 255uy |] + tmp.write_bytes data |> ignore + let result = tmp.read_bytes () + tmp.unlink (missing_ok = true) + result |> equal data + +[] +let ``test Path unlink missing_ok suppresses error`` () = + let tmp = Path "/nonexistent_repo_assist_unlink_xyz.txt" + // Should not raise + tmp.unlink (missing_ok = true) + true |> equal true + +// ============================================================================ +// Directory operations +// ============================================================================ + +[] +let ``test Path mkdir_p and rmdir`` () = + let dir = Path.cwd () / "__pathlib_test_dir__" + dir.mkdir_p () + dir.is_dir () |> equal true + dir.rmdir () + dir.exists () |> equal false + +[] +let ``test Path iterdir returns entries`` () = + let dir = Path.cwd () + let entries = dir.iterdir () |> Seq.toList + entries.Length > 0 |> equal true + +[] +let ``test Path glob`` () = + // Create a file, glob for it, clean up + let tmp = Path.cwd () / "__pathlib_glob_test__.txt" + tmp.write_text "glob" |> ignore + let matches = (Path.cwd ()).glob "__pathlib_glob_test__*.txt" |> Seq.toList + tmp.unlink (missing_ok = true) + matches.Length >= 1 |> equal true From 1217c7a6768e11edc83fc08d59f0e9be814b1ade Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 26 Apr 2026 12:58:28 +0200 Subject: [PATCH 2/3] fix(pathlib): make Path constructor emit positional args Fable emits primary-ctor parameters as Python kwargs, but pathlib.Path.__init__ does not accept `path=` as a keyword, breaking 27 tests with `TypeError: PurePath.__init__() got an unexpected keyword argument 'path'`. Switch to a no-arg primary ctor and declare the string and varargs ctors via [] so emission stays positional. Also relax suffixes/parents/parts to `seq<_>` to match the underlying tuple/list/_PathParents return types, and wrap the byte fixture in builtins.bytes so write_bytes receives a real bytes object instead of a fable.UInt8Array. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/stdlib/Pathlib.fs | 19 +++++++++++++------ test/TestPathlib.fs | 8 +++++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/stdlib/Pathlib.fs b/src/stdlib/Pathlib.fs index 476cb6d..4523c62 100644 --- a/src/stdlib/Pathlib.fs +++ b/src/stdlib/Pathlib.fs @@ -8,13 +8,20 @@ open Fable.Core /// Represents a filesystem path on the current OS (POSIX or Windows). /// Paths are immutable; operations return new Path instances. +/// +/// `Path()` represents the current directory (`.`). For multi-segment construction +/// use the `/` operator (`Path "a" / "b" / "c"`) or `joinpath`. /// See https://docs.python.org/3/library/pathlib.html#pathlib.Path [] -type Path(path: string) = +type Path() = + /// Construct a Path from a single string segment. + [] + new(path: string) = Path() + /// Construct a Path by joining multiple path segments. - /// Equivalent to Path(parts[0]) / parts[1] / … + /// Equivalent to ``Path(parts[0]) / parts[1] / …``. [] - new([] paths: string[]) = Path("") + new([] paths: string[]) = Path() // ------------------------------------------------------------------------- // Properties @@ -34,7 +41,7 @@ type Path(path: string) = /// All file extensions of the final component (e.g. [".tar"; ".gz"]). /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.suffixes - member _.suffixes: ResizeArray = nativeOnly + member _.suffixes: string seq = nativeOnly /// The logical parent of the path (directory containing this path). /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parent @@ -42,11 +49,11 @@ type Path(path: string) = /// Immutable sequence of the logical ancestors of the path. /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parents - member _.parents: ResizeArray = nativeOnly + member _.parents: Path seq = nativeOnly /// The path's components as a tuple of strings. /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parts - member _.parts: ResizeArray = nativeOnly + member _.parts: string seq = nativeOnly /// The root component of the path (e.g. "/" on POSIX), or "". /// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.root diff --git a/test/TestPathlib.fs b/test/TestPathlib.fs index ca4cad9..25854d4 100644 --- a/test/TestPathlib.fs +++ b/test/TestPathlib.fs @@ -2,6 +2,7 @@ module Fable.Python.Tests.Pathlib open Fable.Python.Testing open Fable.Python.Pathlib +open Fable.Python.Builtins // ============================================================================ // Construction @@ -12,6 +13,11 @@ let ``test Path construction from string`` () = let p = Path "/tmp" p.str () |> equal "/tmp" +[] +let ``test Path construction from multiple segments`` () = + let p = Path("/foo", "bar", "baz.txt") + p.str () |> equal "/foo/bar/baz.txt" + [] let ``test Path cwd returns absolute path`` () = let p = Path.cwd () @@ -201,7 +207,7 @@ let ``test Path write_text and read_text`` () = [] let ``test Path write_bytes and read_bytes`` () = let tmp = Path.cwd () / "__pathlib_test_bytes__.bin" - let data: byte[] = [| 0uy; 1uy; 2uy; 255uy |] + let data = builtins.bytes [| 0uy; 1uy; 2uy; 255uy |] tmp.write_bytes data |> ignore let result = tmp.read_bytes () tmp.unlink (missing_ok = true) From e7ad51895029e8626b17288c05b27142f88fbede Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sun, 26 Apr 2026 13:02:54 +0200 Subject: [PATCH 3/3] style: restore indentation on Pathlib.fs/TestPathlib.fs lines Lost during the merge conflict resolution. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Fable.Python.fsproj | 2 +- test/Fable.Python.Test.fsproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Fable.Python.fsproj b/src/Fable.Python.fsproj index c4817d5..180e747 100644 --- a/src/Fable.Python.fsproj +++ b/src/Fable.Python.fsproj @@ -28,7 +28,7 @@ - + diff --git a/test/Fable.Python.Test.fsproj b/test/Fable.Python.Test.fsproj index 910601e..3cf0beb 100644 --- a/test/Fable.Python.Test.fsproj +++ b/test/Fable.Python.Test.fsproj @@ -34,7 +34,7 @@ - +