Skip to content

Conversation

@ofek
Copy link

@ofek ofek commented Oct 17, 2025

Hello again! This is the second half of what we require in order to start using DotSlash.

This moves over the code for the dotslash Python package I created over the weekend. The ownership transfer on PyPI is in progress.

The package serves a similar purpose to the existing fb-dotslash Node.js package stored in the top level node directory. Some notes:

  • Python 3.9 is EOL at the end of the month so I chose to require 3.10+.
  • The package exposes a single locate function for finding the path to the binary that was installed by the installation. The logic was adapted from equivalents like UV's finder. I optimized the path resolution to perform as little work as necessary and to do so lazily.
    ❯ docker run --rm -it python:3.14 bash
    root@8a442038a1c8:/# curl -fsSL https://github.com/sharkdp/hyperfine/releases/download/v1.19.0/hyperfine-v1.19.0-x86_64-unknown-linux-musl.tar.gz \
    | tar -xzO 'hyperfine-v1.19.0-x86_64-unknown-linux-musl/hyperfine' \
    | install -m 0755 /dev/stdin /usr/local/bin/hyperfine
    root@8a442038a1c8:/# pip install -qqq dotslash uv
    root@8a442038a1c8:/# hyperfine -m 100 --warmup 10 "python -m timeit -n 1 -r 1 -s 'from uv import find_uv_bin' 'find_uv_bin()'"
    Benchmark 1: python -m timeit -n 1 -r 1 -s 'from uv import find_uv_bin' 'find_uv_bin()'
      Time (mean ± σ):      33.6 ms ±   2.4 ms    [User: 25.3 ms, System: 7.6 ms]
      Range (min … max):    30.3 ms …  46.1 ms    100 runs
    
    root@8a442038a1c8:/# hyperfine -m 100 --warmup 10 "python -m timeit -n 1 -r 1 -s 'from dotslash import locate' 'locate()'"
    Benchmark 1: python -m timeit -n 1 -r 1 -s 'from dotslash import locate' 'locate()'
      Time (mean ± σ):      23.5 ms ±   1.0 ms    [User: 17.8 ms, System: 5.7 ms]
      Range (min … max):    22.1 ms …  26.9 ms    127 runs
    
    root@8a442038a1c8:/# # Show time it takes to locate binaries
    root@8a442038a1c8:/# python -m timeit -n 1 -r 1 -s "from uv import find_uv_bin" "find_uv_bin()"
    1 loop, best of 1: 7.71 msec per loop
    root@8a442038a1c8:/# # This includes the time of all imports (still faster)
    root@8a442038a1c8:/# python -m timeit -n 1 -r 1 -s "from dotslash import locate" "locate()"
    1 loop, best of 1: 2.86 msec per loop
    root@8a442038a1c8:/# # This excludes import times to match eager behavior of UV
    root@8a442038a1c8:/# python -m timeit -n 1 -r 1 -s "from dotslash import locate,_locate" "locate()"
    1 loop, best of 1: 1.14 msec per loop
    
  • The shipped binary can be invoked directly with python -m dotslash. If there ever is a desire to represent paths as anything other than strings in the implementation, please don't.
  • Builds require setting the DOTSLASH_VERSION environment variable to the desired release tag of DotSlash (the v is optional). This will be used as the package version and, by default, for fetching the appropriate release artifact.
  • Rather than making HTTP requests during builds, you can set the DOTSLASH_SOURCE environment variable to the path to a directory containing the release artifacts. I strongly recommend that the release process uses that eventually (and the Node.js package's build script gains support).
  • I remove build instructions from the content of the PyPI project's landing page since the information wouldn't be useful for users.
  • I moved the release jobs of the downstream packages into a separate workflow that only executes when called by the primary release workflow. I already configured Trusted Publishing on PyPI to use the release-downstream.yml workflow from this repository. You might find hazy details about their support for reusable workflows but this comment provides the full picture. Basically, the claim they chose happens to work for the most nested called workflow when using reusable workflows but not the top level one. Whenever support for that happens there will be no user impact for existing supported scenarios.

cc @sdwilsh @bigfootjon for review as requested

Also, it's worth noting that PyPI was blocking the name dotslash due to certain rules and @di very graciously provided the override 🙇‍♂️

@meta-cla meta-cla bot added the cla signed label Oct 17, 2025
@meta-codesync
Copy link
Contributor

meta-codesync bot commented Oct 17, 2025

@facebook-github-bot has imported this pull request. If you are a Meta employee, you can view this in D84891338. (Because this pull request was imported automatically, there will not be any future comments.)

@sdwilsh sdwilsh requested review from bigfootjon and sdwilsh October 17, 2025 22:26
@sdwilsh sdwilsh self-assigned this Oct 17, 2025
@sdwilsh
Copy link
Contributor

sdwilsh commented Oct 17, 2025

This moves over the code for the dotslash Python package I created over the weekend. The ownership transfer on PyPI is in progress.

I have accepted this invitation, but I won't complete the ownership transfer until this gets merged in.

I am pretty happy with how this looks at a quick glance, but I will do a more thorough review next week. I will probably open a PR on your fork to address some of the devcontainer stuff I see that should be addressed with this as well.

@ofek
Copy link
Author

ofek commented Oct 18, 2025

Thanks, sounds good! I pushed some final cleanup changes like making sure the licenses are shipped with each wheel.

Copy link
Contributor

@sdwilsh sdwilsh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

back to you for mostly minor stuff. This is great, and thanks for putting it together!

@@ -0,0 +1,159 @@
name: publish downstream packages
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you include the --- to indicate the start of a yaml doc please?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do this in a separate PR since the other CI files don't have this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just get right for the new files; you don't need to update other stuff.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Comment on lines +27 to +28
>>> import dotslash
>>> dotslash.locate()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make a pytest test that does this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added tests.

Comment on lines +34 to +38
The installed DotSlash binary can be invoked directly by running the `dotslash` module as a script.

```
python -m dotslash path/to/dotslash-file.json
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add a new python-test command in the Justfile and then run that in our CI to verify this continues to work as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this and also added a line to make it work on Windows for me.

Comment on lines +1 to +7
line-length = 120

[lint.flake8-tidy-imports]
ban-relative-imports = "all"

[lint.isort]
known-first-party = ["dotslash"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annoyingly, we don't seem to have a global ruff.toml file that I can just have included by default. Internal linters are not upset with the formatting here, so it's fine, but something for me to look into in the future I guess -_-

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should enable ufmt: https://ufmt.omnilib.dev/en/stable/

(unfortunately, private wiki links follow)

@sdwilsh see: https://www.internalfb.com/wiki/Python/code_formatting/ruff/

We should follow this wiki: https://www.internalfb.com/wiki/Python/code_formatting/pyfmt/#replicating-pyfmt-in-ope

Which will require updating the imported Diff a bit. @sdwilsh do you have capacity to go do that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Ruff unsupported internally i.e. you must use ufmt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this makes sense. All the ruff things I saw were for other open source projects.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will see if I can get this working today. I'm unfortunately off tomorrow, so if it doesn't happen today, I'll get it resolved on Monday.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like ufmt can use ruff, if I'm reading the internal wiki properly, so I will see about making this work today.

Copy link
Member

@bigfootjon bigfootjon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable, but I think we need to reflect pyfmt correctly. I don't really have capacity right now but Shawn might

(sorry for how long it took to review this PR)

Comment on lines +1 to +7
line-length = 120

[lint.flake8-tidy-imports]
ban-relative-imports = "all"

[lint.isort]
known-first-party = ["dotslash"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should enable ufmt: https://ufmt.omnilib.dev/en/stable/

(unfortunately, private wiki links follow)

@sdwilsh see: https://www.internalfb.com/wiki/Python/code_formatting/ruff/

We should follow this wiki: https://www.internalfb.com/wiki/Python/code_formatting/pyfmt/#replicating-pyfmt-in-ope

Which will require updating the imported Diff a bit. @sdwilsh do you have capacity to go do that?

@ofek
Copy link
Author

ofek commented Oct 23, 2025

Okay, I think I addressed everything now! The only exception is the Ruff/ufmt feedback but as you know I don't have access to the documentation on what needs doing.

@bigfootjon
Copy link
Member

@sdwilsh can you re-review? And message me internally about what to do about the formatter stuff?

@ofek
Copy link
Author

ofek commented Oct 25, 2025

The error is happening on main as well; the last successful run was on September 18. It started failing on September 30 with a commit that seemingly only modified dependencies of the website.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants