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

Enable short URLs in the playground #6383

Merged
merged 5 commits into from
Aug 11, 2023
Merged

Enable short URLs in the playground #6383

merged 5 commits into from
Aug 11, 2023

Conversation

charliermarsh
Copy link
Member

@charliermarsh charliermarsh commented Aug 7, 2023

Summary

This PR adds a Workers KV-based database to the playground, which enables us to associate shared snippets with a stable ID, which in turn allows us to generate short URLs, rather than our existing extremely-long URLs.

For now, the URLs are based on UUID, so they look like https://play.ruff.rs/a1c40d58-f643-4a3e-bc23-15021e16acef. (This URL isn't expected to work, as the playground isn't deployed; it's only included as an example.)

There are no visible changes in the UI here -- you still click the "Share" button, which copies the link to your URL. There's no user-visible latency either -- KV is very fast.

For context, with Workers KV, we provision a Workers KV store in our Cloudflare account (wrangler kv:namespace create "PLAYGROUND"), and then create a Cloudflare Worker that's bound to the KV store via the wrangler.toml:

name = "db"
main = "src/index.ts"
compatibility_date = "2023-08-07"

kv_namespaces = [
  { binding = "PLAYGROUND", id = "672e16c4fb5e4887845973bf0e9f6021", preview_id = "0a96477e116540e5a6e1eab6d6e7523e" }
]

The KV store exists in perpetuity, while the Worker can be updated, deployed, removed, etc. independently of the KV store. The Worker itself has unfettered access to the KV store. The Worker is exposed publicly, and just does some basic verification against the request host.

@charliermarsh charliermarsh added the playground A playground-specific issue label Aug 7, 2023
@@ -0,0 +1,105 @@
{
Copy link
Member Author

Choose a reason for hiding this comment

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

(This is generated by wrangler init.)

@charliermarsh charliermarsh force-pushed the charlie/urls branch 3 times, most recently from 29561f7 to d9ad973 Compare August 7, 2023 04:48
settingsSource: string,
pythonSource: string,
): Promise<void> {
const id = uuidv4();
Copy link
Member Author

Choose a reason for hiding this comment

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

Perhaps this should instead be a truncated hex string of the hash, so that you get a stable URL for a given snippet?

Copy link
Member

Choose a reason for hiding this comment

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

What about hash collisions?

I guess it depends on the desired UX:

  • Should users be able to keep making changes to the linked version even after sharing (and support different versions)
  • or do we want unique URLs for each possible playgorund.

Copy link
Member

Choose a reason for hiding this comment

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

I'd expect the second one for now.

Copy link
Member

Choose a reason for hiding this comment

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

I worry about truncated hash collisions though?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I think the second one is the correct model. It would perhaps be nice if hitting Share multiple times on the same snippet gave you the same URL though, that's what I meant by "Stable URL" (same content leads to same URL).

Copy link
Member

Choose a reason for hiding this comment

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

What I like about astexplorer.net is that the workflow is explicit about when it creates a new gist vs updating the existing one.

The Rust playground creates a new gist whenever you hit save. (Gists everywhere)

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Neat. A few follow up questions

  • Do all core contributors have the necessary permissions to log-in to our KV storage?
  • Does this break existing playgrounds? If so, would it be difficult to continue supporting the old URL format to not break links in issues?
  • How does the frontend authenticate against the key value storage?

playground/db/README.md Outdated Show resolved Hide resolved
"Access-Control-Allow-Origin": "*",
};

switch (request.method) {
Copy link
Member

Choose a reason for hiding this comment

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

Could you add some documentation about the supported URL schema? Or / and refactor out the common path (getting the PLAYGROUND env variable and doing some sort of slicing on the pathname (this is where an inline comment would be useful, what's the thing we remove?

Could we use url.hash? (assuming this is what you're slicing off)

playground/src/Editor/Editor.tsx Outdated Show resolved Hide resolved
Copy link
Member

@MichaReiser MichaReiser Aug 7, 2023

Choose a reason for hiding this comment

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

Nit: Move outside of Editor and/or rename to api?

playground/src/Editor/db.ts Outdated Show resolved Hide resolved
playground/src/Editor/db.ts Outdated Show resolved Hide resolved
settingsSource: string,
pythonSource: string,
): Promise<void> {
const id = uuidv4();
Copy link
Member

Choose a reason for hiding this comment

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

What about hash collisions?

I guess it depends on the desired UX:

  • Should users be able to keep making changes to the linked version even after sharing (and support different versions)
  • or do we want unique URLs for each possible playgorund.

Comment on lines 24 to 26
if (!response.ok) {
throw new Error("Failed to save.");
}
Copy link
Member

Choose a reason for hiding this comment

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

Can we include some details from the response to ease debugging?

@charliermarsh
Copy link
Member Author

Do all core contributors have the necessary permissions to log-in to our KV storage?

They will, once we add folks to the Cloudflare team. I intentionally created this in the team Cloudflare account rather than my personal :)

Does this break existing playgrounds? If so, would it be difficult to continue supporting the old URL format to not break links in issues?

It does break existing playgrounds but I can fix it.

How does the frontend authenticate against the key value storage?

So because the site is public facing, I don't know if there's anything we can do that will be completely unspoofable. My plan is to just guard based on the request host in the Worker, so there's at least something. But even an API key would be spoofable. (We should definitely not expose deletions on the public API though.)

@MichaReiser
Copy link
Member

MichaReiser commented Aug 7, 2023

They will, once we add folks to the Cloudflare team. I intentionally created this in the team Cloudflare account rather than my personal :)

I would prefer holding off with this PR until this happened. It otherwise prevents other people from contributing to the playground. Do we have a setup for external contributors?

So because the site is public facing, I don't know if there's anything we can do that will be completely unspoofable. My plan is to just guard based on the request host in the Worker, so there's at least something. But even an API key would be spoofable. (We should definitely not expose deletions on the public API though.)

Okay. It would help me if you can add some more context to the PR how this looks deployed (I'm not familiar with CF workers). Do we deploy our own backend and the backend uses a KV store? The question then is how we authenticate against the frontend?

Have you considered using a github gist instead? The nice thing about a gist is that it could also be shareable in issues because it stores separate files for the source and configuraiton.

@charliermarsh
Copy link
Member Author

I would prefer holding off with this PR until this happened. It otherwise prevents other people from contributing to the playground. Do we have a setup for external contributors?

Can you describe how this prevents others from contributing to the playground? Why is access to this functionality required to contribute to the playground?

@MichaReiser
Copy link
Member

Can you describe how this prevents others from contributing to the playground? Why is access to this functionality required to contribute to the playground?

I probably don't understand the architecture. So I don't know. Maybe the question should be different. Can external contributors make changes to the playground without having to set up their own backend (including share functionality)?

@charliermarsh
Copy link
Member Author

I probably don't understand the architecture. So I don't know. Maybe the question should be different. Can external contributors make changes to the playground without having to set up their own backend (including share functionality)?

The setup no longer requires logging in to Cloudflare for any development. wrangler dev --local runs a local key-value store and persists the data locally.

@charliermarsh
Copy link
Member Author

Have you considered using a github gist instead? The nice thing about a gist is that it could also be shareable in issues because it stores separate files for the source and configuraiton.

This is interesting but aren't the local development and auth challenges here much harder, since you'd need a GitHub API key in order to develop locally? I suppose we'd also still need a Worker so that we could deploy the API key to a server rather than making requests from the client directly. Workers and KV are also fast enough that there is no discernible latency vs. using local storage, which is a nice property.

@charliermarsh
Copy link
Member Author

Does this break existing playgrounds? If so, would it be difficult to continue supporting the old URL format to not break links in issues?

Existing URLs are now supported.

@charliermarsh charliermarsh force-pushed the charlie/urls branch 2 times, most recently from c4805f1 to 7e81b89 Compare August 7, 2023 21:09
@zanieb
Copy link
Member

zanieb commented Aug 7, 2023

  1. Nothing is persisted until the share button is pressed, correct?
  2. Can we easily egress data from the KV store if we want to switch providers?

@charliermarsh
Copy link
Member Author

Nothing is persisted until the share button is pressed, correct?

Correct.

Can we easily egress data from the KV store if we want to switch providers?

Yes, we can paginate over the KV store (list keys) and export the key-value pairs, but it would admittedly require writing some kind of script to do the export itself (e.g. https://github.com/stevenpack/cloudflare-workers-kv-export).

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

The code changes look good to me. I would find a short note saying that we now have a backend service (maybe call it api rather than db because the db is the key value store) useful.

We should also look into how we want to protect the API endpoint. At least deploy what cloudflare gives us to avoid trivial attacks

@charliermarsh
Copy link
Member Author

I would find a short note saying that we now have a backend service (maybe call it api rather than db because the db is the key value store) useful.

I expanded in the README, but let me know if I'm misinterpreting the request.

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Looks good. Please take a look at the error handling in db.ts and grant the team permission to cloudflare.

playground/README.md Show resolved Hide resolved
playground/api/README.md Outdated Show resolved Hide resolved
playground/api/src/index.ts Show resolved Hide resolved
playground/src/Editor/db.ts Outdated Show resolved Hide resolved
playground/src/Editor/db.ts Outdated Show resolved Hide resolved
@MichaReiser
Copy link
Member

I thought about the hash collision problem a bit more and think it would be good to make the API less generic, so that it can act more intelligently. We don't need to do this as part of this PR but I think it is a worthwhile improvement:

  • Change the POST (should probably be PUT) API to accept the playground state as JSON payload
  • The API generates a key based on the payload and tries to get an entry with the key
    • If an existing entry is present
      • If the payload is identical, return the key
      • Otherwise add a -{i} or similar to the input before re-hashing the data. Retry
    • If no entry exists, create it
  • Return the key

This still leaves the risk of a race, but this is extremely unlikely (needs a hash collision + race).

@charliermarsh
Copy link
Member Author

I’m happy to make the IDs content-addressed as described, but I don’t know that I feel the need to design around hash collisions. We can just use the full SHA if we want, right?

@MichaReiser
Copy link
Member

I’m happy to make the IDs content-addressed as described, but I don’t know that I feel the need to design around hash collisions. We can just use the full SHA if we want, right?

Thank's for pushing back. I'm sometimes too fast with my ideas. I forgot that we're using uuid keys, and the likelihood of a uuid collision is extremely low. Moving the uuid generation to the server (and returning it rather than having the client provide it) could be a nice change because it allows us to drop the uuid dependency from the frontend code. Adding a loop to testing for uuid collisions is straightforward but probably not worth the effort. So we could keep the API as is (client provides a content string), except that the server computes the id

@charliermarsh
Copy link
Member Author

Sounds good. Do you have a preference between (1) server generates a UUID, or (2) server hashes the contents and returns the full SHA as the ID? (The latter would mean that we return the same URL given the same playground contents, which is a nice property, but isn't fully required.)

@MichaReiser
Copy link
Member

Sounds good. Do you have a preference between (1) server generates a UUID, or (2) server hashes the contents and returns the full SHA as the ID? (The latter would mean that we return the same URL given the same playground contents, which is a nice property, but isn't fully required.)

UUID seems simpler but I don't have a strong preference. And changing it later is easy enough.

@charliermarsh charliermarsh enabled auto-merge (squash) August 11, 2023 02:27
@charliermarsh charliermarsh merged commit 5633745 into main Aug 11, 2023
14 checks passed
@charliermarsh charliermarsh deleted the charlie/urls branch August 11, 2023 02:31
durumu pushed a commit to durumu/ruff that referenced this pull request Aug 12, 2023
## Summary

This PR adds a [Workers
KV](https://developers.cloudflare.com/workers/runtime-apis/kv/)-based
database to the playground, which enables us to associate shared
snippets with a stable ID, which in turn allows us to generate short
URLs, rather than our existing extremely-long URLs.

For now, the URLs are based on UUID, so they look like
https://play.ruff.rs/a1c40d58-f643-4a3e-bc23-15021e16acef. (This URL
isn't expected to work, as the playground isn't deployed; it's only
included as an example.)

There are no visible changes in the UI here -- you still click the
"Share" button, which copies the link to your URL. There's no
user-visible latency either -- KV is very fast.

For context, with Workers KV, we provision a Workers KV store in our
Cloudflare account (`wrangler kv:namespace create "PLAYGROUND"`), and
then create a Cloudflare Worker that's bound to the KV store via the
`wrangler.toml`:

```toml
name = "db"
main = "src/index.ts"
compatibility_date = "2023-08-07"

kv_namespaces = [
  { binding = "PLAYGROUND", id = "672e16c4fb5e4887845973bf0e9f6021", preview_id = "0a96477e116540e5a6e1eab6d6e7523e" }
]
```

The KV store exists in perpetuity, while the Worker can be updated,
deployed, removed, etc. independently of the KV store. The Worker itself
has unfettered access to the KV store. The Worker is exposed publicly,
and just does some basic verification against the request host.
renovate bot referenced this pull request in allenporter/pyrainbird Aug 19, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://beta.ruff.rs/docs)
([source](https://togithub.com/astral-sh/ruff),
[changelog](https://togithub.com/astral-sh/ruff/releases)) | `==0.0.284`
-> `==0.0.285` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/ruff/0.0.285?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/ruff/0.0.285?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/ruff/0.0.284/0.0.285?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ruff/0.0.284/0.0.285?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>astral-sh/ruff (ruff)</summary>

###
[`v0.0.285`](https://togithub.com/astral-sh/ruff/releases/tag/v0.0.285)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.0.284...v0.0.285)

#### What's Changed

##### New rules

- \[`flake8-pytest-style`] Implement `pytest-unittest-raises-assertion`
(`PT027`) by [@&#8203;harupy](https://togithub.com/harupy) in
[https://github.com/astral-sh/ruff/pull/6554](https://togithub.com/astral-sh/ruff/pull/6554)
- \[`flake8-pytest-style`] Implement
`pytest-duplicate-parametrize-test-cases` (`PT014`) by
[@&#8203;harupy](https://togithub.com/harupy) in
[https://github.com/astral-sh/ruff/pull/6598](https://togithub.com/astral-sh/ruff/pull/6598)
- \[`flake8-tidy-imports`] Implement `banned-module-level-imports`
(`TID253`) by [@&#8203;durumu](https://togithub.com/durumu) in
[https://github.com/astral-sh/ruff/pull/6378](https://togithub.com/astral-sh/ruff/pull/6378)
- \[`pylint`] Implement `bad-dunder-name` (`W3201`) (in the Ruff
nursery) by [@&#8203;LaBatata101](https://togithub.com/LaBatata101) in
[https://github.com/astral-sh/ruff/pull/6486](https://togithub.com/astral-sh/ruff/pull/6486)
- \[`pylint`] Implement `subprocess-run-check` (`W1510`) by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[https://github.com/astral-sh/ruff/pull/6487](https://togithub.com/astral-sh/ruff/pull/6487)
- \[`ruff`] Implement `quadratic-list-summation` (`RUF017`) by
[@&#8203;evanrittenhouse](https://togithub.com/evanrittenhouse) in
[https://github.com/astral-sh/ruff/pull/6489](https://togithub.com/astral-sh/ruff/pull/6489)

##### Rule changes

- \[`flake8-bugbear`] Add autofix for `B006` by
[@&#8203;qdegraaf](https://togithub.com/qdegraaf) in
[https://github.com/astral-sh/ruff/pull/6131](https://togithub.com/astral-sh/ruff/pull/6131)
- \[`flake8-pyi`] Avoid applying `PYI055` to runtime-evaluated
annotations by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6457](https://togithub.com/astral-sh/ruff/pull/6457)
- \[`flake8-self`] Allow `os._exit` accesses in `SLF001` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6490](https://togithub.com/astral-sh/ruff/pull/6490)
- \[`perflint`] Ignore `PERF203` if `try` contains loop control flow
statements by
[@&#8203;evanrittenhouse](https://togithub.com/evanrittenhouse) in
[https://github.com/astral-sh/ruff/pull/6536](https://togithub.com/astral-sh/ruff/pull/6536)
- \[`pylint`] Check for invalid format type specifiers in nested
replacements for `PLE1300` by
[@&#8203;zanieb](https://togithub.com/zanieb) in
[https://github.com/astral-sh/ruff/pull/6616](https://togithub.com/astral-sh/ruff/pull/6616)
- \[`tryceratops`] Omit `NotImplementedError` from `TRY003` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6568](https://togithub.com/astral-sh/ruff/pull/6568)

##### Settings

- Respect `.ipynb` and `.pyi` sources when linting from stdin by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6628](https://togithub.com/astral-sh/ruff/pull/6628)
- Support glob patterns for `raises_require_match_for` and
`raises_require_match_for` by
[@&#8203;harupy](https://togithub.com/harupy) in
[https://github.com/astral-sh/ruff/pull/6635](https://togithub.com/astral-sh/ruff/pull/6635)

##### Bug Fixes

- Make `lambda-assignment` fix always-manual in class bodies by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6626](https://togithub.com/astral-sh/ruff/pull/6626)
- Fix counting of message arguments when msg is provided as a keyword by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6456](https://togithub.com/astral-sh/ruff/pull/6456)
- Add container types to `E721` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6469](https://togithub.com/astral-sh/ruff/pull/6469)
- Respect scoping rules when identifying builtins by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6468](https://togithub.com/astral-sh/ruff/pull/6468)
- Respect tab width in line-length heuristic by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6491](https://togithub.com/astral-sh/ruff/pull/6491)
- Respect dummy-variable-rgx for unused bound exceptions by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6492](https://togithub.com/astral-sh/ruff/pull/6492)
- Fix detection of top-level imports with newlines in `E402` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6526](https://togithub.com/astral-sh/ruff/pull/6526)
- Allow if-expression with dual string arms in `invalid-envvar-value` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6538](https://togithub.com/astral-sh/ruff/pull/6538)
- Add deprecated unittest assertions to PT009 by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6572](https://togithub.com/astral-sh/ruff/pull/6572)
- Avoid unused argument rules when functions call `locals()` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6578](https://togithub.com/astral-sh/ruff/pull/6578)
- Allow top-level `await` in Jupyter notebooks by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6607](https://togithub.com/astral-sh/ruff/pull/6607)
- Don't detect `pandas#values` for stores, deletes, or class accesses by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6631](https://togithub.com/astral-sh/ruff/pull/6631)
- Avoid removing parentheses in `E712` fix by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6575](https://togithub.com/astral-sh/ruff/pull/6575)
- Skip whitespace between comments at start of file e.g. for `I002` by
[@&#8203;durumu](https://togithub.com/durumu) in
[https://github.com/astral-sh/ruff/pull/6523](https://togithub.com/astral-sh/ruff/pull/6523)
- Add support for nested replacements inside format specifications e.g.
for `PLE1300` by [@&#8203;zanieb](https://togithub.com/zanieb) in
[https://github.com/astral-sh/ruff/pull/6616](https://togithub.com/astral-sh/ruff/pull/6616)

##### Playground

- Shared playground links now use short URLs by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6383](https://togithub.com/astral-sh/ruff/pull/6383)
- Fix possible JSON parse error on playground load by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6519](https://togithub.com/astral-sh/ruff/pull/6519)
- Fix unreachable panic in playground by
[@&#8203;MichaReiser](https://togithub.com/MichaReiser) in
[https://github.com/astral-sh/ruff/pull/6623](https://togithub.com/astral-sh/ruff/pull/6623)

##### Performance

- Improve tokenizer performance for ASCII only identifiers by
[@&#8203;MichaReiser](https://togithub.com/MichaReiser) in
[https://github.com/astral-sh/ruff/pull/6609](https://togithub.com/astral-sh/ruff/pull/6609)

#### New Contributors

- [@&#8203;magic-akari](https://togithub.com/magic-akari) made their
first contribution in
[https://github.com/astral-sh/ruff/pull/6472](https://togithub.com/astral-sh/ruff/pull/6472)
- [@&#8203;durumu](https://togithub.com/durumu) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6378](https://togithub.com/astral-sh/ruff/pull/6378)
- [@&#8203;jamesbraza](https://togithub.com/jamesbraza) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6520](https://togithub.com/astral-sh/ruff/pull/6520)
- [@&#8203;takumaw](https://togithub.com/takumaw) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6533](https://togithub.com/astral-sh/ruff/pull/6533)
- [@&#8203;noklam](https://togithub.com/noklam) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6573](https://togithub.com/astral-sh/ruff/pull/6573)
- [@&#8203;Teraskull](https://togithub.com/Teraskull) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6605](https://togithub.com/astral-sh/ruff/pull/6605)

**Full Changelog**:
astral-sh/ruff@v0.0.284...v0.0.285

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/allenporter/pyrainbird).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi40My4yIiwidXBkYXRlZEluVmVyIjoiMzYuNDMuMiIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
renovate bot referenced this pull request in allenporter/flux-local Aug 20, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://beta.ruff.rs/docs)
([source](https://togithub.com/astral-sh/ruff),
[changelog](https://togithub.com/astral-sh/ruff/releases)) | `==0.0.284`
-> `==0.0.285` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/ruff/0.0.285?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/ruff/0.0.285?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/ruff/0.0.284/0.0.285?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ruff/0.0.284/0.0.285?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>astral-sh/ruff (ruff)</summary>

###
[`v0.0.285`](https://togithub.com/astral-sh/ruff/releases/tag/v0.0.285)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.0.284...v0.0.285)

#### What's Changed

##### New rules

- \[`flake8-pytest-style`] Implement `pytest-unittest-raises-assertion`
(`PT027`) by [@&#8203;harupy](https://togithub.com/harupy) in
[https://github.com/astral-sh/ruff/pull/6554](https://togithub.com/astral-sh/ruff/pull/6554)
- \[`flake8-pytest-style`] Implement
`pytest-duplicate-parametrize-test-cases` (`PT014`) by
[@&#8203;harupy](https://togithub.com/harupy) in
[https://github.com/astral-sh/ruff/pull/6598](https://togithub.com/astral-sh/ruff/pull/6598)
- \[`flake8-tidy-imports`] Implement `banned-module-level-imports`
(`TID253`) by [@&#8203;durumu](https://togithub.com/durumu) in
[https://github.com/astral-sh/ruff/pull/6378](https://togithub.com/astral-sh/ruff/pull/6378)
- \[`pylint`] Implement `bad-dunder-name` (`W3201`) (in the Ruff
nursery) by [@&#8203;LaBatata101](https://togithub.com/LaBatata101) in
[https://github.com/astral-sh/ruff/pull/6486](https://togithub.com/astral-sh/ruff/pull/6486)
- \[`pylint`] Implement `subprocess-run-check` (`W1510`) by
[@&#8203;tjkuson](https://togithub.com/tjkuson) in
[https://github.com/astral-sh/ruff/pull/6487](https://togithub.com/astral-sh/ruff/pull/6487)
- \[`ruff`] Implement `quadratic-list-summation` (`RUF017`) by
[@&#8203;evanrittenhouse](https://togithub.com/evanrittenhouse) in
[https://github.com/astral-sh/ruff/pull/6489](https://togithub.com/astral-sh/ruff/pull/6489)

##### Rule changes

- \[`flake8-bugbear`] Add autofix for `B006` by
[@&#8203;qdegraaf](https://togithub.com/qdegraaf) in
[https://github.com/astral-sh/ruff/pull/6131](https://togithub.com/astral-sh/ruff/pull/6131)
- \[`flake8-pyi`] Avoid applying `PYI055` to runtime-evaluated
annotations by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6457](https://togithub.com/astral-sh/ruff/pull/6457)
- \[`flake8-self`] Allow `os._exit` accesses in `SLF001` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6490](https://togithub.com/astral-sh/ruff/pull/6490)
- \[`perflint`] Ignore `PERF203` if `try` contains loop control flow
statements by
[@&#8203;evanrittenhouse](https://togithub.com/evanrittenhouse) in
[https://github.com/astral-sh/ruff/pull/6536](https://togithub.com/astral-sh/ruff/pull/6536)
- \[`pylint`] Check for invalid format type specifiers in nested
replacements for `PLE1300` by
[@&#8203;zanieb](https://togithub.com/zanieb) in
[https://github.com/astral-sh/ruff/pull/6616](https://togithub.com/astral-sh/ruff/pull/6616)
- \[`tryceratops`] Omit `NotImplementedError` from `TRY003` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6568](https://togithub.com/astral-sh/ruff/pull/6568)

##### Settings

- Respect `.ipynb` and `.pyi` sources when linting from stdin by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6628](https://togithub.com/astral-sh/ruff/pull/6628)
- Support glob patterns for `raises_require_match_for` and
`raises_require_match_for` by
[@&#8203;harupy](https://togithub.com/harupy) in
[https://github.com/astral-sh/ruff/pull/6635](https://togithub.com/astral-sh/ruff/pull/6635)

##### Bug Fixes

- Make `lambda-assignment` fix always-manual in class bodies by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6626](https://togithub.com/astral-sh/ruff/pull/6626)
- Fix counting of message arguments when msg is provided as a keyword by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6456](https://togithub.com/astral-sh/ruff/pull/6456)
- Add container types to `E721` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6469](https://togithub.com/astral-sh/ruff/pull/6469)
- Respect scoping rules when identifying builtins by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6468](https://togithub.com/astral-sh/ruff/pull/6468)
- Respect tab width in line-length heuristic by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6491](https://togithub.com/astral-sh/ruff/pull/6491)
- Respect dummy-variable-rgx for unused bound exceptions by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6492](https://togithub.com/astral-sh/ruff/pull/6492)
- Fix detection of top-level imports with newlines in `E402` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6526](https://togithub.com/astral-sh/ruff/pull/6526)
- Allow if-expression with dual string arms in `invalid-envvar-value` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6538](https://togithub.com/astral-sh/ruff/pull/6538)
- Add deprecated unittest assertions to PT009 by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6572](https://togithub.com/astral-sh/ruff/pull/6572)
- Avoid unused argument rules when functions call `locals()` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6578](https://togithub.com/astral-sh/ruff/pull/6578)
- Allow top-level `await` in Jupyter notebooks by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6607](https://togithub.com/astral-sh/ruff/pull/6607)
- Don't detect `pandas#values` for stores, deletes, or class accesses by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6631](https://togithub.com/astral-sh/ruff/pull/6631)
- Avoid removing parentheses in `E712` fix by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6575](https://togithub.com/astral-sh/ruff/pull/6575)
- Skip whitespace between comments at start of file e.g. for `I002` by
[@&#8203;durumu](https://togithub.com/durumu) in
[https://github.com/astral-sh/ruff/pull/6523](https://togithub.com/astral-sh/ruff/pull/6523)
- Add support for nested replacements inside format specifications e.g.
for `PLE1300` by [@&#8203;zanieb](https://togithub.com/zanieb) in
[https://github.com/astral-sh/ruff/pull/6616](https://togithub.com/astral-sh/ruff/pull/6616)

##### Playground

- Shared playground links now use short URLs by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6383](https://togithub.com/astral-sh/ruff/pull/6383)
- Fix possible JSON parse error on playground load by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[https://github.com/astral-sh/ruff/pull/6519](https://togithub.com/astral-sh/ruff/pull/6519)
- Fix unreachable panic in playground by
[@&#8203;MichaReiser](https://togithub.com/MichaReiser) in
[https://github.com/astral-sh/ruff/pull/6623](https://togithub.com/astral-sh/ruff/pull/6623)

##### Performance

- Improve tokenizer performance for ASCII only identifiers by
[@&#8203;MichaReiser](https://togithub.com/MichaReiser) in
[https://github.com/astral-sh/ruff/pull/6609](https://togithub.com/astral-sh/ruff/pull/6609)

#### New Contributors

- [@&#8203;magic-akari](https://togithub.com/magic-akari) made their
first contribution in
[https://github.com/astral-sh/ruff/pull/6472](https://togithub.com/astral-sh/ruff/pull/6472)
- [@&#8203;durumu](https://togithub.com/durumu) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6378](https://togithub.com/astral-sh/ruff/pull/6378)
- [@&#8203;jamesbraza](https://togithub.com/jamesbraza) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6520](https://togithub.com/astral-sh/ruff/pull/6520)
- [@&#8203;takumaw](https://togithub.com/takumaw) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6533](https://togithub.com/astral-sh/ruff/pull/6533)
- [@&#8203;noklam](https://togithub.com/noklam) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6573](https://togithub.com/astral-sh/ruff/pull/6573)
- [@&#8203;Teraskull](https://togithub.com/Teraskull) made their first
contribution in
[https://github.com/astral-sh/ruff/pull/6605](https://togithub.com/astral-sh/ruff/pull/6605)

**Full Changelog**:
astral-sh/ruff@v0.0.284...v0.0.285

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/allenporter/flux-local).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi40My4yIiwidXBkYXRlZEluVmVyIjoiMzYuNDMuMiIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
playground A playground-specific issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants