Adjust default object bounds [breaking change]

Adjust the object default bound algorithm for cases like &'x Box<Trait> and &'x Arc<Trait>. The existing algorithm would default to &'x Box<Trait+'x>. The proposed change is to default to &'x Box<Trait+'static>.
Note: This is a BREAKING CHANGE. The change has been implemented and its impact has been evaluated. It was found to cause no root regressions on crates.io.
This change was initially discussed as a pre-RFC. In particular there is much discussion there about the strategy towards breaking changes. Based on the reasoning in my last comment, I'm advancing this to "full RFC" status. Note in particular that if we're going to make this change, we have to do it quickly. :)
Rendered view.

I won't repeat myself, but 👎.  Rust 1.0 should be considered the end of the era of breaking changes and going around fixing things to work in the latest compiler, period.

@comex would you prefer a 2.0.0 this early?

I'd prefer that either (a) the change not be made at all, or (b) a version number attribute be used.  I recognize the argument from the comment linked in the PR summary about Rust 1.16 vs. 1.17, but when changes to standard libraries are considered in addition to the language (especially adding new public methods to types and traits, which is always potentially breaking), I believe the advantage to using a version attribute of relatively easily extending the compiler to allow true backwards compatibility (e.g. by hiding those methods, which I've elaborated on elsewhere) outweighs the drawback of version number confusion.

I would prefer a version number be used as well, in general.
As far as this change goes: I think it's early enough that it is okay (under the theory that backwards incompatibility only matters if it really breaks something), but I'm also not someone using Rust in production (which the crates.io lint isn't going to catch).

I doubt that something like this backward-incompatible change would even be considered if it wasn't suggested by someone from core team. I would prefer not making such non-safety related backward-incompatible changes until 2.0. Something like Python's from __future__ import object_bounds would work though.

(Should this and the other RFCs mentioned in the subteam report be tagged final-comment-period?)

In the last week or so, I've seen two instances of people being tripped up by this.  There's this StackOverflow question, and this exchange on #rust.
I'm in 100% agreement that the current rules are unintuitive and baffling, the error message confusing, and the solution completely non-obvious, nor particularly discoverable.  It turns out that the current rules are rubbish.  :P
Given that, and the lengths that have been gone to in order to locate code this breaks... I think this is an acceptable break under these specific circumstances.

I agree the current rule is unintuitive, but a partial alternative solution to your complaint would be improving the error messages for such cases...

@comex On the other hand, I saw a question today from a user where the solution was explicitly spelled out in the error message.  Improving the message would help, but it doesn't hold a candle to changing the rules so the problem itself happens less often.
If we take it as read that opt-in to breaking changes isn't going to happen (which appears to be the way the wind is blowing at the moment), then I'd rather see this particular change happen now than not.  It sucks, as is almost certainly going to give Rust a bit of a black eye for a while... but it's that or being stuck with it.  I certainly don't know which will have been the correct choice in retrospect, which is why I don't envy the core team on this. :P

:+1:
Been bitten by this. Had to make a similar breaking change in a library (add 'static bounds) to make it actually match my intentions.

@DanielKeep @nikomatsakis I fully agree that this change should be made as soon as possible.
In my somewhat related discussion of breaking API changes, I not only proposed to allow breaking changes for fixing security holes, but also for footguns, if the resulting breakage from the change is less than the breakage resulting from the mis-feature. Following DanielKeep's observations, that seems to be the case here.

+1
Maybe it would be worth to consider providing either

a diagnostic that alerts the user when code breaks due to this change, and informs them how to fix it

or

a way to automatically port old code

during one release cycle, that is, from 1.1. to 1.2.
Breaking-changes that can be automatically applied or at least offer good diagnostics that identify the breakage and show how to fix it are "minor breaking changes". Changes that cannot be automatically identified, change semantics, or break code silently (compiles but different runtime behavior) are "major breaking changes".
I am fine with minor breaking changes between point releases. Major breaking changes should wait till Rust 2.0.

It was found to cause no root regressions on crates.io.

:+1:
I agree with https://github.com/nikomatsakis/rfcs/blob/language-semver/text/0000-language-semver.md and with llogiq, the impact is minimal and the change will not disrupt the user experience, it will improve it.

I agree with @tbu- that something like python's "future imports" is a better solution, like:
#![future_feature(adjusted_default_object_bounds)]
Along with a warning if this attribute is missing:
"The current rule for default object bounds is deprecated, please opt-in the new rule by adding ..."

While I agree that we should go ahead and make the change, I think we should also go the extra mile to make sure that any code that might be affected can keep working, be automatically fixed, or something of the sort. (The version-based opt-in, for example.) Importantly, I think we should do so even if there's no indication from crates.io that it's strictly necessary, as a gesture that we take the backwards compatibility issue seriously.

Would it be possible to try and infer some superposition of 'a and 'static and decide later based on whether 'a results in an error?

Hear ye, hear ye. This RFC was moved into Final Comment Period as of Wed, June 11th. (Sorry, forgot to add this notice!)

@aturon just suggested to me that we should add an opt out marker to restore the older defaults. This marker could hang around indefinitely. This means that even if your code breaks, all you have to do is add this marker to the top of your crate to get back the old defaults for now (and you can remove it at your leisure). This would be very simple to maintain in the compiler. Seems like a good idea.
My main concern about the opt-out marker, though, is that I would want to use an attribute name that we can generalize in the future, and I'm not sure what that should be. I propose #[legacy(...)], where the content is a series of names for legacy rules to be used. In this particular case:
#[legacy(default_object_lifetime_bounds)].
Misuse of this attribute would not be an error, but rather a lint, to allow for future expansion.

Regarding diagnostics, I'd like to investigate how to improve them to be more targeted (and perhaps suggest the #[legacy] attribute).

@glaebhoerl

While I agree that we should go ahead and make the change, I think we should also go the extra mile to make sure that any code that might be affected can keep working, be automatically fixed, or something of the sort.

A #[legacy] annotation seems close to this. I don't think it's possible to "automatically fix" or accept older code, except perhaps via a version annotation. I'm not a big fan of version annotations -- even though I initially proposed one! -- for the reasons I outlined in the discuss thread.

+1 let's not shoot ourselves in the foot by allowing the problem to persist. It's already known that the impact is minimal.

I don't think it's possible to "automatically fix"

Why is that?
Let's say you have inference A and B. Let A result in the old, B in the new behaviour. Do the lifetime analysis with B. If an error occurs, back up, retry with A. If an error still occurs, show it, otherwise issue a warning that the code relies on outdated behaviour that may go away in the next version and go on. This may be a naive and slow implementation, but I wouldn't call it impossible.

@llogiq

Let's say you have inference A and B. Let A result in the old, B in the new behaviour. Do the lifetime analysis with B.

I spoke too strongly. I don't think it's possible to fix this in a local, simple fashion. I agree that if we exhaustively searched throughout the entire crate and tweaked defaults, we could do it, but keep in mind that if the type appears in a fn boundary, then we have to go check the callers to decide which usage they expected (and of course callers can disagree). So I should say it's not feasible to accept crates and deduce what default they were expecting. In any case, I also consider that undesirable -- I want simple rules, not some curious hodgepodge. That is, if we tried to accept the older defaults, we'd in fact be creating a scheme with very complex inference behavior that would be very challenging to support. I'd much rather just stick with the current defaults if that were the alternative. :)

I added some text about the #[legacy] attribute.

I'm worried this could set a dangerous precedent, especially for something that seems to be more a quality of life change than anything else.

I only have one comment about the #[legacy(default_object_bounds)] attribute. What will be the name of the next tweak of default object bounds? Can this name be changed to something more descriptive? In my experience naming something legacy is not too robust, it only works if that stuff has only two versions. I don't know enough about this issue and I admit that I did not read all these comments:) Ignore this if my argument is not applicable:)

@nikomatsakis I agree that it is probably infeasible, or at least would make the implementation very brittle, probably also slow down stuff horribly. So it appears we end up with two options:

Make the change as quickly as possible (to reduce the risk of breaking code being written), with a #[legacy(default_object_bounds)] attribute. Be prepared for public backlash (all naysayers will shout "RUST IS STILL UNSTABLE!?  at once, which will induce an level 6 earthquake somewhere midwest). One very real, if improbable downside: Some people may rely on other people's broken private packages, which they may not change for legal reasons, and they now are fixed on 1.0.0 forever.
Step back a bit. Take a deep breath. We can do this change slowly and deliberately, as I have outlined in an old comment on internals: 1. warn if people rely on inference, suggest new behaviour and give a version estimate  when it will break (while still implementing old rules), 2. wait until next minor version, 3. implement new rules, remove the warning. We will have to live with the old rules for some time (but at least get a good suggestion in the warning, which should reduce the cost). Conservatives will be at ease.

Choose your battle.

I wrote a discuss comment outlining some of the advantages of legacy, copied here for convenience:
====
I wanted to note an idea here that for such "course corrections" (as @nikomatsakis aptly dubbed them), it makes a lot of sense to use an opt-out rather than an opt-in. The proposed opt-out would be a crate-level attribute like #![legacy(default_object_bounds)], which you can use to recover the old behavior.
An opt out for such cases has several nice properties:

Most importantly, it means that the breakage is truly minimal in all cases: at worst, you have to add a single attribute to the crate to fix it. We retain the guarantee of hassle-free upgrades.

But, since we believe there to be very little code that will actually break as a result of this change, we likewise would expect very few crates to have to apply the attribute.

Once we add support for legacy in the compiler, it becomes possible to straddle new and old versions by using the attribute. Suppose we make a change in 1.4 with a legacy opt out. If you use the opt-out, you should still be able to compile your code on 1.3 -- it won't recognize the opt out, but it doesn't need to, because it already has the old behavior!

Unlike opt-in flags, these legacy flags would not tend to accumulate over time for code tracking stable Rust. On the contrary, there is good incentive to remove use of the flag (similar to addressing deprecation warnings).

@aturon the only downside of this is dependencies – if your crate depends on my crate which now needs a legacy attribute to work, and you cannot get me to change my crate, you're b0rked.
This is incidentally why I proposed a target version attribute in my RFC PR. Unlike a legacy flag, it doesn't get stale.

@llogiq

@aturon the only downside of this is dependencies – if your crate depends on my crate which now needs a legacy attribute to work, and you cannot get me to change my crate, you're b0rked.

Hm, I don't follow. This attribute, at the coarsest level, would apply per crate, so there's no problem linking crates that use the attribute together with those that don't.

@aturon the problem is with crates you depend on that rely on old behavior but have no legacy attribute. You seem to assume everyone can change all crates they depend on. That assumption may not be valid everywhere, due to legal or personal constraints.
At the very least one would need to have a cargo/rustc option to enable a certain legacy flag on a certain crate, but even that could get messy fast.

@llogiq Ahh, I see now. And yes, worst case we could handle this externally.

If rustc is going to know how to apply both sets rules, then it sounds better to use version tags like @llogiq says.
The version defaults to the latest version if omitted, so newcomers and new projects get the new rules.
The problem comes if users think the version attribute governs more than it's designed for. It might not for example select the version of the libstd or another minor change that was introduced without keeping an option open for the old behaviour.

@nikomatsakis, @aturon

I propose #[legacy(...)], where the content is a series of names for legacy rules to be used.

I would personally prefer to not take the route of #[legacy] just yet as I feel like we haven't worked through the implications yet. (for example working through @llogiq's RFC).
One concrete worry of mine is that this sort of intermingling of various compiler feature sets can lead to surprising behavior. These worries can of course be overcome, they're just annoyances that may start to pile up over time:

If crate A has the old defaults, but crate B has the new defaults, we've gotta be super careful (in terms of compiler bugs) to ensure the metadata for A encodes that it has the old defaults and when crate B links to A it takes this all into account.
Code now may not be able to be copy/pasted between two crates. Whether or not a piece of code compiles may rely on some far-away #[legacy] annotation.

Unlike opt-in flags, these legacy flags would not tend to accumulate over time for code tracking stable Rust. On the contrary, there is good incentive to remove use of the flag (similar to addressing deprecation warnings).

I do agree with this, however, that if we add a system like this I'd tend to lean towards opt-out instead of opt-in, but I share @llogiq's concerns in that updating deps may not always be the easiest thing (but I suspect it's basically always possible).

@alexcrichton

If crate A has the old defaults, but crate B has the new defaults, we've gotta be super careful (in terms of compiler bugs) to ensure the metadata for A encodes that it has the old defaults and when crate B links to A it takes this all into account.

Anything that would show up in metadata is probably a poor candidate for an "opt-in" change, since that implies it is deeper somehow. This change, for example, does not affect metadata one way or another.

I do agree with this, however, that if we add a system like this I'd tend to lean towards opt-out instead of opt-in, but I share @llogiq's concerns in that updating deps may not always be the easiest thing (but I suspect it's basically always possible).

In my view, the reason that legacy is preferred over something that Just Works is precisely because it doesn't Just Work. In other words, legacy is not intended to make breaking changes "free" -- it's intended to make transitioning easier, but still a speedbump.

In my view, the reason that legacy is preferred over something that Just Works is precisely because it doesn't Just Work

Yeah this is a good point, it both allows backwards compatibility with low overhead while continuing to provide pressure to migrate to modern conventions/idioms (but not overly aggressively so).

All that said, I'm amenable to the idea of moving #[legacy] out. I'm also amenable to a warning, or just landing this in 1.2, but I'm concerned that it will make the change higher impact overall, since people will see warnings when their code would have worked just fine with the new defaults. I'm not sure if we can target the warnings better.

@nikomatsakis I'm quite worried about a warning that fires in cases that would not be affected by this change; I think we should only do it if it can be highly targeted.
As to legacy, I think (1) we should go ahead and claim the attribute, so that we have this available in the future and (2) if we're right about the extent of breakage here (i.e., very little or none), then essentially no one will end up using this particular legacy flag anyway, so having it does relatively little harm; whereas if we're wrong, it provides a route around breakage.
In any case, I do agree with @alexcrichton that aggressively backporting the change is probably more rushed than it needs to be -- rolling it out in 1.2 beta seems like a good approach.

We could also explicitly state that the legacy mode will only persist for a fixed duration, rather than indefinitely. That was the original intention anyhow.

-1
To add breaking changes in a 1.1 that is really only a quality of life improvement hurts really badly. Save up a list of these for 2.0 and use that time to figure out how to integrate these kinds of changes in a more user friendly way.

I really don't think this is compelling enough to justify breaking code or breaking users' confidence in the Rust authors' commitments to not breaking code. If anything, the change should be an opt-in with possible listing for 2.0 (so a feature flag would enable this behavior, and who cares if it ends up in everyone's preamble). The thing is that any argument against making this feature opt-in can be changed into a stronger argument against making it opt-out: every inconvenience of having to add the feature to new code is doubled when you have to disable it on old code.

In my view, the reason that legacy is preferred over something that Just Works is precisely because it doesn't Just Work. In other words, legacy is not intended to make breaking changes "free" -- it's intended to make transitioning easier, but still a speedbump.

Who cares? If you've already said that things will Just Work, the salient feature of #legacy[] isn't that it has a better semantic relationship to the goals of the project.

I support this change for a few reasons:

It appears to be a quite sizable win.
It seems unlikely to break much/any code in practice.
Even without legacy, it is relatively straight forward to go through and fix any code that does break by adding annotations
Code can support both old and new compilers at the same time by being more explicit.

@bluss: I would advise against using current version as default for now. All code out there has no target version declaration, so we'd break that code by default! My suggestion is actually to default to 1.0.0 and add a target version on cargo new (also perhaps write a nice message on compile that no target version was specified). We should not change this behavior until the next major version.
In the meantime, I have amended my RFC PR to include legacy and future flags in the alternatives section. I really like the idea of combining both features, so that each target version defines a core feature set, as well as permissible legacy and future features, which crates can declare to use them. This would make the whole design very flexible, while keeping sane defaults for everyone without requiring special contortions on either the core team's nor the users` sides.

-1 on the opt out, and the entire change as is for reasons of breaking backwards compatibility. I think it could be an opt-in feature, however, perhaps with a helpful lint suggesting that code that utilizes these default bounds should opt-into this feature for better experience. I acknowledge the argument that these will tend to accumulate, but I sincerely hope you aren't planning on making these breaking changes very often. You can remove them in Rust 2.0.

In my view, the reason that legacy is preferred over something that Just Works is precisely because it doesn't Just Work.

I really don't understand this view.  It is a fact of life that codebases get abandoned all the time; indeed, while this happens in all programming languages, I suspect this would be a bigger concern in ecosystems like Rust's that promote small libraries, which are more likely to get to a point where the author considers them complete and unlikely to require further changes (except compatibility fixes).  Some abandoned codebases (both libraries and applications) may end up bitrotting anyway due to dependencies or other issues, but many will stay usable indefinitely... unless the language breaks them.  Compare Python 2 and its long tail of modules.
In this case at least, it helps that the legacy attribute can stay around forever, so in theory all the user has to do is paste one line into their local copy of the crate.  Except that if, say, a crate that compiled two years ago and has been left alone since then starts emitting compiler errors, it is likely to not be immediately obvious whether the breakage is caused by (a) a broken semver dependency, (b) a breaking change (which one? stick on random legacy attributes until it works?), (c) a misconfiguration of the system doing the build, (d) a compiler bug, etc.  And if the user is just someone (or some distro buildbot) trying to compile an application, who may not even know how to program in Rust or at all, they may be out of luck unless they find some record of the same issue on the Internet.  This is awful UX.
It's one thing to find a version attribute too onerous to require, but to consider such breakage a good thing?
And in practice it may well make people involved in in-house projects afraid to update their compilers, leaving them on random old versions forever, which is bad for everyone.

My two cents:
I could imagine that it would be possible to add legacy attributes externally to a crate, via cargo.
At that point we should consider requiring crates in stable Rust to specify the exact version of the Rust compiler that they need (e.g. 1.2). That way cargo could add these legacy attributes automatically independently of the version of the rust compiler used, and breakage would be really hard to achieve.
In unstable Rust we could allow something like requiring 1.2-nightly, but I would be against of allowing this required rustc version attribute to "most recent" if breakage is to be prevented.
I think that figuring out how to prevent crates from ever breaking, even in the presence of breaking changes, has much higher priority than fast compile times (a fast compiler is useless if it can compile "valid 1.0" code).

@gnzlbg Your proposal boils down to a weaker version of my target version proposal, because it relies on cargo inserting legacy attributes, while whoever uses rustc directly would also have to specify them directly.
This would routinely break compiletest.rs, whenever a new legacy attribute is added. As I said before, target versions never get stale, while opt-ins/-outs can be forgotten (or simply not be present in a code base), and adding them through cargo externally is an ugly hack.
Now with my proposal, cargo only has to automatically insert the current rust version as target version (either by asking rustc or by loading some lib that supplies it) on new (and perhaps issue friendly warnings on build --release or something).
However, the idea of being able to add individual feature opt-in/out flags to the rustc command line sounds like something we may want to explore further.

@nikomatsakis

A #[legacy] annotation seems close to this. I don't think it's possible to "automatically fix" or accept older code, except perhaps via a version annotation. I'm not a big fan of version annotations -- even though I initially proposed one! -- for the reasons I outlined in the discuss thread.

I think either a version-based or a feature-based opt-in or -out (#[legacy]) would be fine as far as this goes -- I'm mostly concerned with optics and precedent. This being the first time we do this, we are effectively advertising that this is how potentially breaking changes in Rust are going to be handled. So I think it's important that we have a solid and reassuring policy we can communicate.

@comex
When I said that "the reason that legacy is preferred over something that Just Works is precisely because it doesn't Just Work", I was being overly cute. I was intending to allude to my earlier argument that making course corrections carries a cost that goes beyond breaking code, and that if we make it too easy to make small tweaks to the language, we will carry on doing so even when we shouldn't have.

In some discussions with others, I realized that although I tried to write the RFC in a way that reflected that there were underlying principles being proposed here, that was not entirely clear. Therefore, I'm going to push an update that makes some edits to RFC #1122, just basically copying over bits of this RFC. The key bit are these general guidelines for when a course correction like this might be considered:

All data indicates that correcting this flaw will break extremely little
or no existing code (such as crates.io testing, communication with production
users of Rust or other private developers, etc).
The feature was only recently stabilized, preferably in the previous
cycle. This minimizes the possibility that a large body of code has
crept up that relies on this feature.

If and when we establish LTS releases, we should never make
changes to features marked as stable in a LTS release (except for
soundness reasons).

There is no backwards compatible way to repair the problem.

(The RFC already mentioned various mitigation measures, including #[legacy], so I just made those sections a bit more concrete.)

@llogiq

We can do this change slowly and deliberately, as I have outlined in an old comment on internals: 1. warn if people rely on inference, suggest new behaviour and give a version estimate when it will break (while still implementing old rules), 2. next minor version: Make it an error to rely on inference, with the same suggestion as before, 3. next minor version: implement new rules, remove the error

I find this approach very appealing in the abstract! If we find ourselves in this situation again (oh please no!), then I might very well like to adopt a strategy like this. In the end, though, it's still a breaking change, no matter how far we space it out. What we're talking about is what is the appropriate set of steps to take towards mitigating the breakage. Given the estimated impact of this change, and the reasonable chance that it will actually just make things better, I still feel like the mitigation step of rolling it out for a beta cycle is sufficient, particularly with the #[legacy] flag (though some have argued to me it is overkill for this particular case).
Part of the calculus here is that getting a quality warning without false positives is non-trivial in this particular case. I have been meaning to look into that code and find better heuristics for reporting lifetime inference failures, but I'm not sure if I will have time to do so before the next release, and even if I did, it would certainly mean deferring the other work I've been doing on optimization and soundness changes. It's hard to justify that for this change.

It's hard to justify that for this change.

This is the first breaking change post-1.0.0, which has gotten it a lot of visibility – perhaps more than really warranted. Setting a good precedent will assuage fears about further instability instability and setting up language versioning infrastructure now will allow us to move faster in the future.

Part of the calculus here is that getting a quality warning without false positives is non-trivial in this particular case.

You already know where in the code this particular inference kicks in (or you would not be able to change it). So emit the warning whenever the lifetime is inferred. Add a link to a 'language evolution' page (I will gladly help setting this up). The page can explain the required steps.
Then we get the target version machinery in place, and the following steps should be trivial.

My opinion as a user of Rust: Rust 2.0 will come eventually. And it's very likely that more problems of Rust 1.0 will be found in the next months. The most reasonable way to approach this problem is to schedule the release of Rust 2.0 in two years in the future and gather feedback in the meantime.
Two years should be a reasonable timespan to gain experience and plan improvements on a language that is already very well designed but may still have some hidden flaws. And no one will complain that version 2.0 after two years time is fast. (And two years can go by pretty fast).
Personally I would also like to get rid of the issue discussed in this thread but I think it's just too likely that there will be more issues in the future and therefore it's better to stay true to the stability promises.

@jbethune: Why wait two years when we can fix the problem now without breaking anything?

@llogiq: That's one way to see it. And I do not deny that it does make perfect sense from a technical perspective. I know the Rust devs don't take such a breaking chance lightly and personally I would be totally okay with this breaking change because I know the devs don't do this on a whim.
But if you want to compete with C and C++ you should also keep in mind that these languages have a really good track record of backwards compatibilty. And to some people this is really important. And the Rust devs also know this. That's why they have given the stability promise.
My perspective is: Rust is already pretty awesome. But like every software project there are undiscovered bugs/design flaws. And more will be discovered. If the Rust team now sticks to their promise that they will not introduce a backwards incompatible change, this will send out a strong positive message to the rest of the programming community.
And the cool thing about semantic versioning is that we will have a Rust 2.0 one day and then all the discovered design flaws can be corrected together. And by officially scheduling the release of 2.0 for a specific date in the future no one gets the impression that we ignore design flaws.
This is all about long-term thinking from a technical and from a political/psychological perspective. But feel free to disagree with me :)

That's why my plan (as outlined above, on internals and in my RFC PR) makes this breaking change in phases while ensuring that no code actually breaks. With target version definition per crate, we would in fact have perfect backwards compatibility.
The team has reserved a right to change inference behavior during minor version changes, as long as no actual code breaks. I believe if we introduce this change in the phases I've outlined, everyone will have plenty time to adapt (and the warning message I've proposed will even tell them how). Can you tell me what waiting two years for this change will accomplish? (Oh and please also think about all other almost-breaking changes that are being proposed in the meantime)

@jbethune, In C++ the 2.0 essentially never happens, most design flaws are kept for the sake of backwards compatibility. In Rust we're going to make the changes and it will have the impact. We can make this impact smaller by doing the change while it still affects nobody.

@jbethune Every single release of the C++ standard has broken backwards compatibility in multiple ways. The devil is in the details since either:

the code was already broken, or
the old behavior can be provided as a language extension (by just switching a compiler flag), or
the break is not silent (that is, it results in a compilation error), and

a good diagnostic can be emitted, or
a tool for automatically porting code can be written.

If a feature is removed a better alternative must be provided.

For this reason I think it is important that Rust decides which kinds of breakage are fine within point-releases, and which aren't.
As I said above, as long as we can:

provide a good diagnostic and/or an automated tool to fix it,
a compiler flag/attribute to enable the old behavior, and
third-party crates that our software requires but are outside our control can be still compiled correctly by new compilers (either because we can activate the flag for a crate externally, or because cargo handles this for us somehow automatically),

then the breakage is "minor". I think "minor" breaking changes are fine within point releases.

@llogiq so, you're proposal to have a round of targeted warnings was nagging at me, and I had a thought on how I might be able to do it. I'm happy to say that I was able to implement an experimental implementation without so much pain. I have a branch that issues warnings for code that will break when the defaults change, but not other code -- it's probably somewhat approximate, but seems to be pretty close in my tests.
I've been thinking it over and I'm thinking that the policy ought to roughly be:
When making a breaking change, there needs to be a transition plan in place to make the breaking change as painless as possible. Here are some guidelines.

When possible, issue a release that gives warnings when changes will be required.

These warnings should be as targeted as possible -- if the warning is too broad, it can easily cause more annoyance than the change itself.
To maximize the chance of these warnings being taken seriously, the warning should not be a lint. The only way to disable it is to make a change that will be forwards compatible with the new version.
After a suitable time has elapsed (at least one cycle, possibly more), make the actual change.

If warnings are not possible, then include a #[legacy] attribute that allows the old behavior to be restored.

Ideally, this #[legacy] attribute will only persist for a fixed number of cycles.

If #[legacy] is not possible, it is only permissible to make the change if it is required for soundness. Even then, it's worth considering whether there is another avenue.

If a breaking change is not motivated by soundness concerns, then additional considerations apply:

The change must be predicted to have very minimal impact on existing code.
To help ensure the accuracy of predictions, the change must only affect systems that were recently stabilized.

(If/when we issue LTS releases, I would change the final bullet point to simply say that the change must not affect code running on an LTS release.)

@nikomatsakis Sorry if my proposal has brought you distress, but I'm glad to hear it had a somewhat good outcome :smile:
I wholeheartedly agree with your guidelines, except I still oppose the use of legacy flags, for the reasons I explained before – we cannot expect people to be able to change other people's code to add them.

@nikomatsakis

Ideally, this #[legacy] attribute will only persist for a fixed number of cycles.

I feel you and I wish that we will never need a Rust 2.0. I wish that the solution would allow for a future Rust 1.15 crate to seamlessly depend on a Rust 1.0 crate.
@llogiq

I wholeheartedly agree with your guidelines, except I still oppose the use of legacy flags, for the reasons I explained before – we cannot expect people to be able to change other people's code to add them.

What if one could also pass them to rustc as a parameter?

@gnzlbg

What if one could also pass them to rustc as a parameter?

This would get very messy, fast, once you have multiple dependencies that may need different legacy flag combinations.
It would make deployment of any rust-based solution much more complicated than necessary, because dammit, the information about what language version the code uses belongs in the code! (Sorry, did I become loud? breathe deeply...now I'm better. Ok,)
I've been arguing for target-version based API / language evolution for some time now. So much that I fear it's getting stale. People still stick to the idea of opt-in or opt-out, as if it was an easy or even workable solution (pretty pretty please read my RFC PR #1147 for an explanation why it's not).
@nikomatsakis
I've already answered your comment, but I feel I need to stress another point:

Ideally, this #[legacy] attribute will only persist for a fixed number of cycles.

Ideally, this #[legacy] attribute will never be used anywhere. Because it means that people must act to keep their code (or the code their code depends on) from breaking. Please, let's set up a fellowship of Rustaceans to take the very idea of #[legacy] to the fiery lava pits deep within Mordor's mountains and throw it into the sizzling hot lava, so it may never corrupt the beautiful Rustic homelands again.

@llogiq

This would get very messy, fast, once you have multiple dependencies that may need different legacy flag combinations.

Oh, you are right. I was thinking that I could tell cargo externally that a package requires Rust version 1.0. If I try to compile it with Rust 1.13 cargo could look up the flags it needs to pass to rustc to compile this package. It could potentially be a very long list of flags, and certainly messy for cargo developers, but as a users I wouldn't need to worry about it much.

the information about what language version the code uses belongs in the code!

I gotta sleep over this but right now I would agree that it belongs at the crate level at least in the Cargo.toml. Having it in the source files would make me right now a bit uncomfortable, but I'm open to give this some more thought over the next couple of days.

I've already answered your comment, but I feel I need to stress another point:

Ideally, this #[legacy] attribute will only persist for a fixed number of cycles.

Ideally, this #[legacy] attribute will never be used anywhere. Because it means that people must act to keep their code (or the code their code depends on) from breaking. Please, let's set up a fellowship of Rustaceans to take the very idea of #[legacy] to the fiery lava pits deep within Mordor's mountains and throw it into the sizzling hot lava, so it may never corrupt the beautiful Rustic homelands again.

I think that a fine grained solution is a good start tho. We can have legacy attributes for each breaking change, legacy attributes for whole rust versions #[legacy(rust-1.1)] that are expanded by rustc to a collection of attributes, and a way to pass these attributes to rustc externally so that you only need to write this in the Cargo.toml file. Such a layered approach might allow some to be on nightly, but not on the latest nightly.

@gnzlbg I actually included opt-in / opt-out by flag (be it legacy flag or otherwise) as an alternative/extension in my RFC PR, and I intend to move them into the main proposal once I have thought the consequences through.
I agree that allowing for more fine-grained control is a worthy goal, in addition to setting up a good default by the target version. This means we get sane defaults, break no code and still can have all unstable or legacy features we may want by inserting the corresponding flags.

As a newcomer to Rust and having been badly bitten by this issue, I'd say yes, merge ASAP.
Now, on the subject on how to make breaking changes on point releases, llogiq's idea of a phased change looks to me to be the best trade off. Possibly make the change available early using the existing compiler features mechanism.
As for opt-out and target API version, keep in mind that in a thriving ecosystem, unmaintained code that just works never stays unmaintained for long: if some piece of code is really useful, there's always someone to fork it, dust it off and add the latest bells and whistles to it. That said, it could come in handy when a major release of Rust comes out with loads of breaking changes. But please, not for point releases, we'd end up in a dependency hell: what if you have code that uses libc targeted at the current Rust version while using at the same time a crate that uses a libc version targeted at previous, incompatible, Rust version? I know it's doable, but no thanks.
When Rust 12.0 comes out, the best place for a target API flag would however be in the Cargo.toml file:

target 1.0? compile with Rust 1.x.y
no target? compile with latest

And make it so that Rust 12.0 can be installed along with previous versions (like gcc does for example) so that cargo can invoke the appropriate version. Oh, and provide some vetting tool to help transition code from one version to the other.

@db47h

[...] in a thriving ecosystem, unmaintained code that just works never stays unmaintained for long [...]

This is expressly not about unmaintained code. It's about enterprise users who may have invested money in vetting one version of a given solution, which you now ask to spend more money to switch to another. It's about users of (not yet existing, but conceivable) proprietary crates, which they are contractually obligated not to change. Finally it's about all users, because we're going to lose an awful lot of them once the next few point-releases break their build and they start to fear new Rust versions.

[...] what if you have code that uses libc [...]

libc hasn't changed too much in a long time, even in the face of severe security issues. Also we're already abstracting over it, so I don't think this will be a problem. Even if it comes to that, we can figure out how to deal with it then.

[...] the best place for a target API flag would however be in the Cargo.toml file

I thought about this, too, but this has two downsides:

I for one don't always use cargo (for example when creating small tests or benchmarks), so this would at least require an additional way to add it to the build without cargo – perhaps a rustc argument, but this is easy enough to forget or get wrong.
When copying code from elsewhere, you must also copy the target version from the Cargo.toml, lest your copied code will probably stop working. This is at least unintuitive; whereas having an attribute on the crate root is in line with other crate-global definitions we already have.

no target? compile with latest

I sure hope you meant this as a rule for Rust 12.0.0 – because if enacted now it would break all builds with the next incompatible release.

@llogiq
Well, working for an open source minded shop, I didn't think about the untouchable proprietary crate.
My concern here is that making provisions to target point version APIs would pave the way for real breaking changes in point releases and dependency hell. The issue discussed in this PR should be an exception: everyone who's been bitten by this has already added 'static all over the place, and although it is a potentially breaking change, it does not seem to break any publicly available code. As for closed code for which no one has spoken up yet, a phased implementation should make everyone happy.

libc hasn't changed too much in a long time [...]

I only picked libc as an example, my point is still valid for any other crate.

[...] Finally it's about all users, because we're going to lose an awful lot of them once the next few point-releases break their build and they start to fear new Rust versions.

I fully agree. Then don't allow breaking changes at all. As much as I'd like to see this PR merged, I'd rather see it postponed to Rust 2.0 and properly documented as a known issue than open Pandora's box to dependency hell (nothing wrong with known issues as long as they are properly documented).

[...] perhaps a rustc argument [...]

Why not, as long as it's only for major releases ;) But that's not incompatible with having it as a config value in Cargo.toml or a crate root attribute.

I sure hope you meant this as a rule for Rust 12.0.0 – because if enacted now it would break all builds with the next incompatible release.

Well, I jumped to version 12 for a reason ;) But I'm not sure what you mean. When the next backward incompatible Rust version will come out (say 2.0 for example), for which Rust version will existing code be compiled if there is no target hint in the sources? 1.0, 2.0? Take for example gcc 4.8.2: although supporting some of the C++11 standard, it defaults to -std=gnu90. Do you mean that Rust will/should take the same approach?

@db47h I don't see your point.
Why should we stop evolving the language (and API) when we can do so safely – that is, as long as the old behavior is accessible via target version/legacy/future combination and we can ensure crates of all target versions continue to work together?
Yes, it would force people to upgrade their rust versions to use code that is written for the new versions. That is a good thing and it's no different than in, say, Java, or C++. We want people to use the newest Rust, because if they don't, they'll miss out on all the fixes for all problems we may have found in the meantime.

[...] for which Rust version will existing code be compiled if there is no target hint in the sources?

Currently, that will be 1.0, because we cannot ask people to retrofit a target version to all their code. And yes, this is much like the default of --std=c90. Note that my proposal included that cargo new insert the current version as target by default.
Also future incompatible versions will likely have incompatible APIs, which (as I've written in my RFC PR) could be use to determine a lower bound for the target version. In any event, we may have some time until the next major release hits, so once most code declares its target version, a warning + best-effort-compilation with the current version could be the most useful way to go (this could of course be overridden by a compiler argument).

@llogiq : Took me a while to find the RFC PR you mention :-P  And yes, makes more sense now that I've read it.
I'm not saying the language should stop evolving, not at all. Sorry if that's how I came through. There's nothing wrong with your RFC-PR, on the contrary.
The dependency hell I'm referring to occurs for example when your code and some other crate it depends on both use a different target version of yet another crate (see my poorly chosen libc example). I don't know about Java, but in my experience this is all too common with C/C++ (game engines come to mind) . You refer to it as "breakage" in your RFC-PR, I used a different term, coming from a different perspective, that's all.
Of course, it won't happen if your PR goes through and if everyone adopts newer Rust versions quickly.

Please note that target version as currently defined refers to rust (including its std) only. Whether we want to allow others to use the concept is an open question (however, I've made the syntax extensible to allow for this case).
Also as of now, crates already can refer to different versions of other crates via Cargo.

As for opt-out and target API version, keep in mind that in a thriving ecosystem, unmaintained code that just works never stays unmaintained for long

I'd generally disagree with this - haven't you ever found some website offering (relatively obscure) software in a tarball that's 5 years old, with no development, upstream or fork, in sight?  Or even in GitHub, where there may be, say, 125 "forks", of which, according to GitHub's network view, the vast majority are unchanged from their fork date, a dozen have one or more commits added, which may or may not fix the problem you're having, and none show signs of active ongoing development.  Those numbers come from a real example - a C library where the maintainer introduced a trivial but critical bug back in 2013 and has not paid attention to the resulting issue report, or practically any issues/PRs, since.  At least GitHub makes it easier to fork a repository, but all the links on the Internet still point to the old version, and committing to the necessary advertising plus attention to the issue/PR queue to make your fork 'canonical' is... not exactly easy.

what if you have code that uses libc targeted at the current Rust version while using at the same time a crate that uses a libc version targeted at previous, incompatible, Rust version? I know it's doable, but no thanks.

To slightly elaborate on what @llogiq just said, this question wouldn't make sense, because depending on a different version of a crate is orthogonal to a Rust version attribute; the attribute, for its part, would be per crate, and crates targeting different versions would fully interoperate.

I'd generally disagree with this - haven't you ever found some website offering (relatively obscure) software [...]

I meant "useful unmaintained code", and discounted the relatively obscure software ;) I just wouldn't worry too much about making sure that old bitrotted code still compiles 10 years from now.

Most software is relatively obscure - the so-called long tail.

@db47h besides, that kind of thinking brought us the y2k problem. It's shortsighted and bad engineering.

It's official... the language subteam has decided to accept this RFC and go forward with this specific change. Given its significance, this PR was also discussed specifically at a recent core team meeting.
Note: although it's been decided to make this particular change, this is explicitly not considered a binding precedent. The more general policy questions are still under active discussion and we plan to eventually open a separate RFC on that topic. For the moment, I am currently working on a post for internals summarizing my thoughts on breaking changes, LTS releases, major versions, and so forth, but this is not yet complete. (Given the upcoming Mozilla work week, this may not get posted right away.) And of course there is also RFC #1147 by @llogiq, which though it was born from a discussion on API deprecation is clearly relevant. --nmatsakis

@nikomatsakis: Thank you for working with us to make this change a reality. I believe this is a good change for Rust and for us all.
Incidentially – and mostly inspired by the discussion here and elsewhere – I have rewritten and streamlined my proposal considerably. As it is now, it incorporates the things that were discussed here, so double thanks to all who argued with me. :smile:

Merged. Tracking issue


missing timestamp method from iroh::client::Entry

It seems that https://github.com/n0-computer/iroh/pull/1854 doesn't have an Entry.timestamp() method 😢. Is that right?

fixed!


ESP32/ESP32-C3: Fix leak of semaphores created by Wi-Fi kernel thread

Summary
This PR intends to provide an alternative solution to the fix provide on https://github.com/apache/incubator-nuttx/pull/4092 for ESP32-C3, and extend it to the ESP32 Wi-Fi driver.
Originally, the semaphores created by the Wi-Fi kernel thread for handling application connection requests were not being destroyed, causing the a memory leak of 32 bytes for every wapi invocation.
The ESP32-C3 solution is being refactored in order to avoid the usage of on_exit in driver code, see: https://github.com/apache/incubator-nuttx/pull/6197
Impact
Fix for semaphore leak on ESP32 and refactor of current solution on ESP32-C3.
Testing
esp32-devkitc:wapi
esp32c3-devkit:wapi

One question from my side. Do we expect multi-instance of wifi driver? If not, then maybe we can just have a global semaphore pointer and use that on/atexit?
I mean I do not fully understand neither pthread_key nor task_tls_ usage here.
Maybe it is reasonable to have static pointer to semaphore and if it is NULL, the allocate and init it. Then at/onexit the static pointer can be checked again and free the memory. Am I missing something?

The Wi-Fi library creates a new semaphore for every thread that performs connection operations, so we cannot have a global pointer.
Since these semaphores are thread-local, this motivated the initial implementation based on pthread_key_t, so that the semaphores were being stored in Thread Local Storage, and then could be destroyed on thread termination. The solution here was based on the one implemented for ESP-IDF, which works as expected.
But on NuttX it resulted in the semaphores not being destroyed. I'll try to explain why.
The Wi-Fi library operates in a dedicated Kernel Thread, named wifi. But the pthread_key_t and the destructor for the semaphores were allocated to the Thread Local Storage of the init thread.
Every network-related request from the application will be handled by the wifi kernel thread and its child pthreads. The issue is that those child pthreads do not belong to the same Task Group from the init thread, which is the one whose TLS area contains the semaphore destructor.
So the catch here is that NuttX provides this process-like abstraction which segregates pthreads created from different tasks. So a pthread created from Task B won't be able to share keys with another pthread from Task A.

Do we expect multi-instance of wifi driver?

No, the Wi-Fi driver does not expect to be initialized more than once.

my config had TLS_TASK_NELEM=0 and i got a bit surprised by this change breaking the build.
does Kconfig have a way to solve this kind of things in a bit more user friendly way?

Task tls is disabled by default.:(

One question from my side. Do we expect multi-instance of wifi driver? If not, then maybe we can just have a global semaphore pointer and use that on/atexit?

The Wi-Fi library creates a new semaphore for every thread that performs connection operations, so we cannot have a global pointer. Since these semaphores are thread-local, this motivated the initial implementation based on pthread_key_t, so that the semaphores were being stored in Thread Local Storage, and then could be destroyed on thread termination. The solution here was based on the one implemented for ESP-IDF, which works as expected.
But on NuttX it resulted in the semaphores not being destroyed. I'll try to explain why. The Wi-Fi library operates in a dedicated Kernel Thread, named wifi. But the pthread_key_t and the destructor for the semaphores were allocated to the Thread Local Storage of the init thread. Every network-related request from the application will be handled by the wifi kernel thread and its child pthreads. The issue is that those child pthreads do not belong to the same Task Group from the init thread, which is the one whose TLS area contains the semaphore destructor.
So the catch here is that NuttX provides this process-like abstraction which segregates pthreads created from different tasks. So a pthread created from Task B won't be able to share keys of type pthread_key_t with another pthread from Task A.

Yes. I just reexamined the task tls code and see that I did a wrong assumption.


build-fhs-userenv-bubblewrap: Preserve symlinks in /etc

Description of changes

If the original file in /etc is a symlink, make it a symlink inside the sandbox as well. This PR is a more complete solution to https://github.com/NixOS/nixpkgs/issues/126234#issuecomment-1192203498, replacing #145258.
If you bind-mount an individual file and the file is deleted then recreated, the mountpoint will still refer to the original file and cannot be further bind-mounted:
touch mp1 mp2
echo "original content" >file
sudo mount -o bind file mp1
cat mp1 # "original content"

# delete and recreate the file
rm file
echo "new content" >file
cat mp1 # "original content"

# the steam soldier runtime uses bwrap internally, causing another bind-mount
sudo mount -o bind mp1 mp2 # "mount(2) system call failed: No such file or directory."

Since both /etc/static and /run are bind-mounted already, we should just keep the symlinks inside the sandbox.
Tested in the same manner as in https://github.com/NixOS/nixpkgs/issues/126234#issuecomment-1192203498. I can launch games after disconnecting and reconnecting to Wi-Fi with steam -steamdeck.
Things done

Built on platform(s)

[x] x86_64-linux
[ ] aarch64-linux
[ ] x86_64-darwin
[ ] aarch64-darwin

[ ] For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
[ ] Tested, as applicable:

NixOS test(s) (look inside nixos/tests)
and/or package tests
or, for functions and "core" functionality, tests in lib/tests or pkgs/test
made sure NixOS tests are linked to the relevant packages

[ ] Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
[x] Tested basic functionality of all binary files (usually in ./result/bin/)
22.11 Release Notes (or backporting 22.05 Release notes)

[ ] (Package updates) Added a release notes entry if the change is major or breaking
[ ] (Module updates) Added a release notes entry if the change is significant
[ ] (Module addition) Added a release notes entry if adding a new NixOS module
[ ] (Release notes changes) Ran nixos/doc/manual/md-to-db.sh to update generated release notes

[x] Fits CONTRIBUTING.md.

I believe so. It'd also solve many other trick issues caused by missing symlink in sandbox (eg, wrong timezone in steam client)

Back link a related fix in https://github.com/NixOS/nixpkgs/pull/286360


Update logic-apps-limits-and-config.md

@IlyaGrebnov,
Thanks for your contribution as a Microsoft full-time employee or intern. You do not need to sign a CLA.
Thanks,
Microsoft Pull Request Bot

#sign-off

@IlyaGrebnov : Thanks for your contribution to the Azure documentation! The author, @jeffhollan, has been notified to review your proposed change.


tsdb: Bug fix for further continued deletions after crash deletions; added more tests.

Additionally: Added log line for block removal.
Signed-off-by: Bartlomiej Plotka<EMAIL_ADDRESS>

#7777 jackpot
lgtm

#7777 jackpot
lgtm, nice!

In this PR everything is permitted :)

Let me commit remote write receiver then.... ;p


Add SafeSwap to landing page

📘 Issue Description
Enhance the Landing Page with SafeSwap Branding
The current landing page lacks any visual identity or branding for SafeSwap. We want to incorporate the "SafeSwap" title prominently on the page to establish a strong brand presence. Since we don’t yet have a logo, feel free to experiment with different font styles and placements.
Task Details:

Propose 2-3 design options where the "SafeSwap" title is effectively integrated into the landing page.

Option 1: Place the title prominently in the header/navigation bar for consistent visibility.
Option 2: Feature the title as a central hero element on the page, paired with a tagline or key message.
Option 3: Include the title in the footer or as a watermark-like element for subtle branding.

Experiment with different font types and sizes to explore distinct styles that align with SafeSwap's vision.

Present mockups or design sketches for each option to aid in decision-making.

Notes:

Ensure the title is visually appealing and blends seamlessly with the current landing page design.
Focus on creating a strong and professional look that resonates with users.
Keep the designs responsive and adaptable to various screen sizes.

I’ll love to work on this project and appreciate if am opportune to design and elevate the SafeSwap landing page. I’m confident that my approach will help establish a strong brand presence for SafeSwap and make the landing page both visually appealing and user-friendly. My designs will ensure responsiveness, seamless integration, and adaptability for all screen sizes.

Can I contribute to this one?

I would like to work on this issue

Hi, I'm Josué Brenes and I'll be working on issue.
I'm Dojo Coding member. ⛩
I estimate this will take 1 day to complete.
How I Would Resolve This
To effectively integrate the "SafeSwap" title into the landing page and establish a strong brand identity, I would proceed as follows:

1. Understand the Vision

Create a clean, professional, and visually appealing design for SafeSwap that aligns with its vision of security and reliability.
Explore font styles, sizes, and placements to emphasize the "SafeSwap" branding.

2. Design Options
Option 1: Header/Navigation Bar

Place the "SafeSwap" title prominently in the navigation bar for consistent visibility across all pages.
Use a bold, professional font (e.g., Montserrat, Poppins) with a modern and clean look.
Pair it with a subtle tagline like “Secure Transactions, Simplified.”
Make the title interactive by linking it to the home page.
Responsive Design: Ensure the title adjusts gracefully on smaller screens, possibly replaced by a smaller version or initials (e.g., “SS”).

Option 2: Central Hero Element

Feature the "SafeSwap" title as the primary hero element on the landing page.
Pair it with a tagline or key message, such as:

“SafeSwap: Empowering Secure Transactions Everywhere.”

Use a large, impactful font with a gradient or shadow effect to make it stand out.
Add background elements (e.g., abstract shapes or gradients) that complement the title without overpowering it.
Center the title visually to create a strong first impression for users.

Option 3: Footer/Watermark

Include the "SafeSwap" title in the footer for subtle yet consistent branding.
Experiment with a semi-transparent watermark-style placement in the page background.
Use a lighter or muted font to avoid overpowering other elements.
Ensure the footer includes links or additional resources for user engagement.

3. Font and Style Exploration

Experiment with modern sans-serif fonts like Montserrat, Poppins, or Inter for a professional look.
Use dynamic font sizes:

Large and bold for the hero section.
Medium and clean for the navigation bar.
Subtle and minimalistic for the footer or watermark.

Explore color palettes:

A combination of blues and greens for a trustworthy and tech-savvy feel.
Gradients or accent colors that align with the existing design.

4. Mockups and Sketches

Use tools like Figma or Adobe Illustrator to create mockups for each option:

Option 1: Showcase the title placement in the navigation bar on desktop and mobile views.
Option 2: Design the hero section with the "SafeSwap" title as the focal point, paired with a tagline and complementary background elements.
Option 3: Present the footer with the title or a semi-transparent watermark overlay.

5. Responsive and Adaptive Design

Ensure all designs are fully responsive and adapt to various screen sizes:

Use media queries to adjust font sizes, placements, and spacing.
Test on multiple devices to confirm visual consistency.

6. Testing and Feedback

Share the mockups with stakeholders for feedback and iterate based on suggestions.
Validate that the title integration enhances the landing page’s overall design without detracting from usability or content.

Deliverables:

Three design mockups/sketches for title integration (header, hero section, and footer).
Responsive and adaptive designs optimized for various screen sizes.
Exported design files (PNG/PDF) and Figma/Illustrator project files for further iterations.

Notes:

Keep the design professional and aligned with SafeSwap’s brand vision.
Ensure all designs are easy to implement and maintain consistency across the landing page.
Balance creativity with functionality to engage users effectively.

Can I jump on this task?I can comfortably handle this issues

Can I take care of this issue?
i'm a frontend dev and a blockchain dev kindly assign :)

Hello I am Joseph I am a frontend developer and blockchain developer and I am also an active contributor here on only dust here is my profile https://app.onlydust.com/u/josephchimebuka. This is my first time to contribute to this repo ill appreciate the opportunity to contribute. this is a couple of frontend and blockchain projects i have built https://metacrypt.vercel.app/ https://mattedsgn.com/
May I try this one?

Can I be assigned to this?

Can I grab this task?
My approach:
Will place the SafeSwap text in the middle of the header for max visibility
Will use proper font to make it visible clear
Will add in the footer portion also
ETA-2days

I’d love to work on this task.

Can I be assigned to this?  I am an experienced frontend developer with 3 years of experience.

I'd love to work on this! this is my first ODhack
i'll be able to handles this.
ETA 1day


create first time walkthrough intro

possible frameworks:

http://introjs.com/
https://github.com/heelhook/chardin.js

lets go with http://github.hubspot.com/shepherd/ best to capsulate in a plugin which does introspect which features are available.

created new branch zack-search/feature-intro
@l00mi please review

@StrubT
You did a great job in understanding (fast) the structure of the project and creating the new plugin!
(In general if you do this and see there was no documentation, please just go ahead and write down in a README.md some sentences which would have helped you to start. We notoriously had never enough time for this up to now.)
Now unfortunately on my set-up I get the following error, I did not investigate in detail.
shepherd.js:732 Uncaught TypeError: this.trigger is not a function
    at HTMLAnchorElement.start (shepherd.js:732)
start @ shepherd.js:732

Further I understood that sheperd.js meanwhile seems to be dead too. So I am considering to switch as we did not yet invest too much time yet. (Sorry about that!)
I looked at http://bootstraptour.com/ probably you find something even better?
How much time do you think does it take to switch over to another tour engine?

@l00mi I will have a look into it. But I really like the backdrop / highlighting feature. It should not take too long to switch over. I will look into it Thursday or Friday and get back to you.

I actually did manage to find some other frameworks, but each has its own quirks, so I ended up with the one you suggested.

https://introjs.com/ -- looks good, unclear licencing
http://iamdanfox.github.io/anno.js/ -- great, reaaaaaaly outdated
http://bootstraptour.com/ -- looks good, works with standalone or bundled bootstrap

It took me a while to realise zack-search already uses a native bootstrap variant.
I had to include the 'regular' bootstrap instead because bootstrap-tour explicitly depends on jQuery.
@l00mi if this is not acceptable for you, we may have to choose yet another framework...
cannot reference from commit, so 1e26a719e344dce00839fc358110b2d8462f32e5

@l00mi @bergos Thank you for moving the code from zack-search to www.alod.ch.
However, I have three questions.

Why did you copy intro.js and others, but not remove them from zack-search?

Did you also experience the problem that when loading the site for the first time, the tour did not start?
You should be able to reproduce this problem by removing the stored state.
I did some digging and noticed that they actually use restart() on their own page instead of start(), so I did the same.

@l00mi mentioned that the tour should automatically start when someone visits the site for the first time. Shall I implement that?

removing stored state:
['tour_current_step','tour_end'].forEach(n => localStorage.removeItem(n))

I asked in the chat for feedback. If it works for you, I will remove intro.js in zack-search.
Didn't noticed, but could be. I mainly tested if it's still working after my changes and for sure loaded the page multiple times before I pressed the tour button.
If there is an easy solution, I would prefer some visual highlighting of the question mark. (Can we shake it, like a pupil which likes to be choosen first by the teacher?)

Yes please go ahead @bergos, I will take care of the queries and simple renderer.js
I had also some troubles. I actually would be like to start the tour, just that it might start on the ? itself.
see 2

Sorry @l00mi, I don't get that.


[WIP] Add GPU performance tips for high performance LLMs with JAX/XLA

Documenting all JAX and XLA flags that we use for high performance LLMs with JAX/XLA.
Will update this periodically, and also link to

https://github.com/google/jax/blob/main/docs/gpu_performance_tips.md

Per Yu-Hang's suggestion, will update https://github.com/NVIDIA/JAX-Toolbox/blob/main/README.md#environment-variables to this page as well, once the PR is merged.

@abhinavgoel95, can you please review and provide feedback ?

@abhinavgoel95 or @nouiz, all conversations are resolved. Can one of you please approve, squash commits, and merge ?

@abhinavgoel95 anything else or I can merge now?


Sqlite and Sqlite3 db types fail to start with "out of memory" on v0.23.0-alpha4

Bug description
After updating from headscale v0.23.0-alpha3, to v0.23.0-alpha4, I am unable to start headscale and encounter this error in my journalctl output:
FTL github.com/juanfont/headscale/cmd/headscale/cli/server.go:21 > Error initializing error="unable to open database file: out of memory (14)"
A side note, but I also had to change the "settings.db_type" setting to "settings.database.type" in my nix config. It would be nice to implement a depreciation warning on this setting in the repository's flake.nix.
Environment

headscale v0.23.0-alpha4
Tailscale 1.60.0
NixOS 24.05 - unstable

I have nginx running with a proxypass to headscale, but I've been succesfully using that for a while
To Reproduce
Install headscale v0.23.0-alpha4 with the following settings:
  services.headscale = {
    package = headscale.packages.${pkgs.system}.headscale; // using the flake
    enable = true;
    address = "<IP_ADDRESS>";
    port = 8082;
    settings = {
      server_url = "https://${domain}";
      database.type = "sqlite3";
      dns_config = {
        base_domain = baseDomain;
        extra_records = tailscale_dns_entries;
      };
      derp = {
        auto_update_enable = true;
        update_frequency = "24h";
      };
    };
  };

Duplicate of #1761, fixed in main.


I can't install activat-power-mode

When I install activate-power-mode, the system stuck.

this is still happening with the newest version?

Closing issues on old versions of this package.
Open again if the problem persists with the latest release.


Overhaul pdz.py

pdz.py properly handles .pda files now
switched to ArgumentParser CLI
option to list contents of a pdz file without extracting
option to extract only certain files from a pdz file
experimental option to reconstruct headers for extracted pd* files (possibly incorrect, use at your own risk)

Checked out the branch and tested the script briefly to verify that both listing files and extracting pdz files containing pda files worked. I believe the signature for pdv is incorrect but I'll fix that in a follow-up commit since the page documenting the format is also wrong.
Thanks!


Handle pytz properly

In operations.py, there's code to handle timezones which Db2 doesn't natively support. This requires pytz and when it is not available it tries to raise an exception, but there's a couple problems:

The NotSupportedException is not defined
The exception object is not raised
No code handles the exception

I think we should handle this properly. We could start by using an appropriate exception (maybe local to the module, since it's only used there) and handling it at the two call sites within the module and mapping it to the appropriate Django exception (or don't handle it and instead use the appropriate Django exception directy from _get_utcoffset).
Another, possibly better idea is to just require pytz in order to function so we don't have to handle the case where it is not available.

It looks like Django itself already requires pytz, so we can also require it, making the solution quite simple.

It looks like Django itself already requires pytz, so we can also require it, making the solution quite simple.


Bug: EXTRA_SUBNETS stopped working

TLDR: EXTRA_SUBNETS feature is no longer working when FIREWALL=on
With FIREWALL=on and EXTRA_SUBNETS=<IP_ADDRESS>/24, I can now no longer access a web UI of an attached container, when previously I could.  The attached container is running using the service:name style, and is accessible from other containers, has internet access, and otherwise appears happy.  I just can't reach it from inside the LAN.
If FIREWALL=off is set, I am able to access the web UI.  Let me know if I can provide further information to help (or what verbose logging would help).  Maybe related to #190 ?

Is this urgent?

[ ] Yes
[x] No

What VPN service provider are you using?

[x] PIA
[ ] Mullvad
[ ] Windscribe
[ ] Surfshark
[ ] Cyberghost

What's the version of the program?
Running version latest built on 2020-07-12T21:22:24Z (commit 4cd6b33))

What are you using to run the container?

[ ] Docker run
[x] Docker Compose
[ ] Kubernetes
[ ] Docker stack
[ ] Docker swarm
[ ] Podman
[ ] Other:

Extra information

Logs: Nothing that looks relevant?
Configuration file:
    environment:
      ...
      # Firewall
      - FIREWALL=on
      - EXTRA_SUBNETS=<IP_ADDRESS>/24

Host OS: Ubuntu 20.04

That just got fixed in #190 like an hour ago. Sorry for the disruption! Feel free to comment back if it still does not work.

I agree it seems related, but I believe I'm running the commit with the fix for #190.  Commit is 4cd6b33.

That's the one: https://github.com/qdm12/private-internet-access-docker/commit/4cd6b33044aab006de013cff608ed1d4c9aa55ab
It works for me again (using Shadowsocks), is it working for you?

Also make sure the firewall is on, disabling might impact the routing related to what we want (although it shouldn't but still)

Both Shadowsocks and Tinyproxy are set to off.  The firewall does look to be on, and it reads the set subnets from environment.
2020-07-12T16:49:22.503-0700	INFO	firewall: setting allowed subnets through firewall...,
2020-07-12T16:49:22.503-0700	INFO	routing: default route found: interface eth0, gateway <IP_ADDRESS>,
2020-07-12T16:49:22.503-0700	INFO	firewall: enabled successfully,
2020-07-12T16:49:22.506-0700	INFO	routing: adding <IP_ADDRESS>/24 as route via <IP_ADDRESS> eth0,
2020-07-12T16:49:22.480-0700	INFO	firewall: enabling...,
2020-07-12T16:49:22.480-0700	INFO	routing: default route found: interface eth0, gateway <IP_ADDRESS>,
2020-07-12T16:49:22.480-0700	INFO	routing: local subnet found: <IP_ADDRESS>/24,
<snip>
2020-07-12T16:49:22.578-0700	INFO	firewall: setting VPN connections through firewall...,
2020-07-12T16:49:22.578-0700	INFO	routing: default route found: interface eth0, gateway <IP_ADDRESS>

I have it working with my usual web ui attached.
Maybe your problem is something different indeed.
Can you please send your full docker-compose.yml (omit credentials) and full logs so I can have more information? Thanks

Actually there is a problem, @stumpylog no need to post your config; I'm working on it.

Awesome!  Thanks so much for looking into this.  Great container

Thanks @stumpylog for helping out. It's thanks to you guys that I'm driving this container development like a racer 😉 🚤
So I've fixed the bug, it was the firewall allowing basically traffic between EXTRA_SUBNET and EXTRA_SUBNET (useless) instead of LOCAL_SUBNET and EXTRA_SUBNET. I've tested it with some http server running with "service:gluetun" and it works, so it should -finally- be fixed 👍

Referring my comment in #177, I can confirm that the current :latest build fixes my issue with port forwarding! Thanks for a fantastic container and quick work.


chore: add missing comma in README

Checklist

[X] Used only camelCase variable names.
[X] If functionality is added or modified, also made respective changes to the readme.
[X] Used conventional commits keywords.

thx


[FLINK-27778][table][planner] Use correct 'newName()' method

Fix an issue where the planner was using a method from the wrong class. This is important because the previously used method comes from flink-table-code-splitter which is more or less an implementation detail of the runtime.

@flinkbot run azure

Assuming the code generator and runtime need to agree on how the naming works, why aren't they able to somehow share an implementation of this method?

That's a good question; they could definitely share it if we wanted to.
It would result in table-code-splitter having a new dependency on table-common (presumably, if we move that method there; seems like the only viable spot).
I don't think this would be a problem dependency-wise, because the only user of table-code-splitter is table-runtime, which also depends on table-common.
Maybe this wasn't done intentionally so that table-code-splitter remains self-contained w.r.t. the rest of the table modules; I'm not sure.
I don't think they necessarily must use the same naming scheme.

If they don't need to use the same naming scheme (but just happen to use the same one), then I don't mind the duplication and wouldn't want to add the dependency on table-common.


MVP! Everything is working with redux

Full CRUD operations. Everything is working!!

Everything look good  so far I will go ahead and merge this branch.


[Mentions v2] Handle the new action type ACTIONABLEREPORTMENTIONWHISPER

HOLD https://github.com/Expensify/App/issues/39508
When a user that is member of the policy tries to mention a room that doesn't exist we will send a whisper back asking if they want to create the room they just mentioned, this whisper type will be ACTIONABLEREPORTMENTIONWHISPER .
Resolving the whisper will call the ResolveActionableReportMentionWhisper command with a reportActionID and a resolution, which can be yes or no. The reportActionID is the one of the whisper.
If the whisper is resolved it should not be displayed to the user.
The whisper message will be:

For a single room: "Heads up, reportNames[0] doesn't exist yet. Do you want to create it?"
For two rooms: "Heads up, reportNames[0] and reportNames[1] don't exist yet. Do you want to create them?"
For three or more: "Heads up, reportNames[0], reportNames[1] and reportNames[2] don't exist yet. Do you want to create them?"

Details can be found here in the Mentions V2 design doc.

@rlinoz Do we have any specific ETA which we are aiming for with this one?

I didn't start the backend changes for this one yet, but ideally we would get this done before May 1st.

Hey @robertKozik do you think you can start on this? I started the backend already and as we were talking here this is the order we want to get this deployed to avoid any trouble:

Deploy the front-end to support showing the whisper
Deploy the front-end to support resolving the whisper
Deploy the back-end to support sending the whisper and handling its resolution

It will be a little harder to test, but I think we can manage.

Also updated the action to be ACTIONABLEREPORTMENTIONWHISPER

Looks like there's mocks in the doc, but happy to help. Is there anything needed from a design side on this? 😄

Oh I don't think so, it is just the new feature label I guess

Hey @kadiealexander this is in prod already, but I don't know how we create the Upwork job in new feature issues, can you help please?

Payouts due:

[ ] Contributor: $250 @fedirjh
[ ] Contributor+: $250 @ishpaul777

Upwork job is here.


rename, renamenx and unlink

Adds the three functions that were not exposed.
In particular the renamenx and unlink are very convenient for "quick delete" actions (by renaming to {previous_key}:some_random_value and then unlinking that)

Thanks @to266. I pulled your commits into https://github.com/aembke/fred.rs/pull/105 to resolve the base branch difference, so I'm going to close this one.


fix: Separate MapView disposal from LifecycleOwner changes

#206 introduced a crash when disposing the MapView, as reported in #207. Since the DisposableEffect has multiple keys, changes to any of them will result in the MapView becoming destroyed, which is not necessarily what we want. This repro project (extremely helpful, thank you @thekingrenz23!) revealed a case where the lifecycle owner (one of the DisposableEffect keys) can change without changing the MapView or context. This puts the MapView into a bad state, where it's "destroyed" but still shown and fully interactible.
This moves the MapView disposal into its own DisposableEffect with only the MapView as a key, avoiding the unwanted disposal.
Fixes #207 🦕

Will this be merged? I need this fix

@DSteve595 great find. Thank you!

@thekingrenz23 A release will be made shortly!


Updating the upload command to use the RG group passed by the user

Fixes #8157
This checklist is used to make sure that common guidelines for a pull request are followed.

[x] The PR has modified HISTORY.rst describing any customer-facing, functional changes. Note that this does not include changes only to help content. (see Modifying change log).

[x] I adhere to the Command Guidelines.

@yugangw-msft this came as a CRI from a customer so i am trying to get this in for the upcoming release.


Formatting, Capitalization, and spacing updates

I started using this module at work and thought I'd give back to the project for how much its helped me! (if you're open to my changes)
after reviewing https://github.com/PoshCode/PowerShellPracticeAndStyle, I modified every .ps1 file in this project, aligning the formatting, capitalization, and spacing to the recommended best practice.
I did not do any of the following:
Change any code logic
Remove any code (commented or live)
let me know what you think!

Thanks @EVWorth!  I'm definitely open to contributions!  Let me find some time to review and I'll provide feedback.

Hello,
Thank you for your software, very helpful.
Is it possible to have @EVWorth work merged to the project ?
Is it the software still under development ?

@red-erik, yes it's still maintained and there was a major release 2 weeks ago.  This PR is almost a year old and there are many conflicts that would need to fixed before it could be merged.


analyzer docs are incorrect

This causes issues for displaying of docs on webcomponents.org
Steps to reproduce:
$ npm install --save @polymer/lit-element
$ mv node_modules/@polymer/lit-element/* .
$ polymer analyze --module-resolution node -i lit-element.js

Versions:
lit-element: 0.6.0
polymer-cli: 1.8.0

Expected:
No my-element.
Actual:
Element with odd tag name.
  "elements": [
    {
      "description": "Class decorator factory that defines the decorated class as a custom element.",
      "summary": "",
      "path": "lib/decorators.js",
      "properties": [],
      "methods": [],
      "staticMethods": [],
      "demos": [],
      "metadata": {},
      "sourceRange": {
        "start": {
          "line": 32,
          "column": 29
        },
        "end": {
          "line": 39,
          "column": 1
        }
      },
      "privacy": "public",
      "superclass": "HTMLElement",
      "name": "customElement",
      "attributes": [],
      "events": [],
      "styling": {
        "cssVariables": [],
        "selectors": []
      },
      "slots": [],
      "tagname": "('my-element')\n    export class MyElement extends LitElement {}\n\n    declare global {\n      interface HTMLElementTagNameMap {\n        'my-element': MyElement;\n      }\n    }"
    }
  ],

Source: https://unpkg.com/<EMAIL_ADDRESS>cc @rictic

Is this something we're going to fix?

The actual issue here seems to be Polymer/tools#708, so closing this.


Install the last version of octoDNS from master branch

After using this command python -m pip install . or python setup.py install to install the last version of octoDNS (master branch) it gives me:
Successfully installed UNKNOWN-0.0.0

I can see in your bootstrap script you use pip install -e .[dev,test]. The same issue.

I van verify this is the case. It's not particually important in the bootstrap case since you normally aren't using the installed version (ideally it wouldn't install.)
/cc @4383 who did the setup tools PR in case it's something obvious/easy.

I updated the message.
Successfully installed UNKNOWN

You need to update setuptools before run python setup.py install or python -m pip install
pip install -U setuptools

Ohh, that was easy :) Thank you.


allow pressing sync button on personal repo even when there are uncommitted changes

Have a commit ahead of main and unstaged local changes. No commits behind main.
Press the git sync button in the UI
🐛 See "Please clean your repository working tree before checkout" error. This shouldn't be necessary if I'm not pulling any commits.

unlike claimed in the locked thread #89944, I do not deem this situation as rare, in the sense this is just about the default situation working on personal repos (i.e. no-one else is expected to push).
in that situation, this could just make for an easy 'save my work on the git server', while having i'd opt to just push using the keyboard rather than using the UI button.

This feature request is now a candidate for our backlog. The community has 60 days to upvote the issue. If it receives 20 upvotes we will move it to our backlog. If not, we will close it. To learn more about how we handle feature requests, please see our documentation.
Happy Coding!

This feature request has not yet received the 20 community upvotes it takes to make to our backlog. 10 days to go. To learn more about how we handle feature requests, please see our documentation.
Happy Coding!

:slightly_frowning_face: In the last 60 days, this feature request has received less than 20 community upvotes and we closed it. Still a big Thank You to you for taking the time to create this issue! To learn more about how we handle feature requests, please see our documentation.
Happy Coding!


updated wording on understanding uninitialized variables

Checklist:

[x] I have read freeCodeCamp's contribution guidelines.
[x] My pull request has a descriptive title (not a vague title like Update index.md)
[x] My pull request targets the main branch of freeCodeCamp.
[x] I have tested these changes either locally on my machine, or GitPod.

Closes #45853

This is my first time contributing to an open source project! I work as a full stack developer, so let me know if you need any help. I've included a screenshot below even though its a simple change.

@lharrison1313
b should be defined and have a final value of 15.

@lharrison1313 b should be defined and have a final value of 15.
✅

Hi @lharrison1313. Congrats on your first pull request (PR)! 🎉
Thank you for your contribution to the page! 👍
We are happy to accept these changes and look forward to future contributions. 📝


Add ability to specify signature_version=UNSIGNED using a string

Describe the bug
It looks like boto3 does not support public buckets by default (why?), so everyone has to create a specially configured client:
boto3.client('s3', config=Config(signature_version=UNSIGNED))
The popular MLFlow library has the following client initialization code (simplified):
def create_client():
   return boto3.client('s3', config=Config(signature_version=os.environ.get("S3_SIGNATURE_VERSION", "s3v4")))

Boto Config and RequestSigner attribute signature_version has str type, but there does not seem to be any string that would map to the UNSIGNED python singleton object.
This makes accessing public MLFlow artifact buckets impossible.
Steps to reproduce
os.environ["S3_SIGNATURE_VERSION"] = "unsigned"
...
client = boto3.client('s3', config=Config(signature_version=os.environ.get("S3_SIGNATURE_VERSION", "s3v4")))

Get error:
UnknownSignatureVersionError: Unknown Signature Version: unsigned.

Expected behavior
I expect client = boto3.client('s3', config=Config(signature_version="unsigned")) to succeed and work as expected.
Logs
Full stack trace

/opt/conda/lib/python3.7/site-packages/mlflow/store/artifact/s3_artifact_repo.py in list_artifacts(self, path)
    113         paginator = s3_client.get_paginator("list_objects_v2")
    114         results = paginator.paginate(Bucket=bucket, Prefix=prefix, Delimiter="/")
--> 115         for result in results:
    116             # Subdirectories will be listed as "common prefixes" due to the way we made the request
    117             for obj in result.get("CommonPrefixes", []):

/opt/conda/lib/python3.7/site-packages/botocore/paginate.py in __iter__(self)
    253         self._inject_starting_params(current_kwargs)
    254         while True:
--> 255             response = self._make_request(current_kwargs)
    256             parsed = self._extract_parsed_response(response)
    257             if first_request:

/opt/conda/lib/python3.7/site-packages/botocore/paginate.py in _make_request(self, current_kwargs)
    330
    331     def _make_request(self, current_kwargs):
--> 332         return self._method(**current_kwargs)
    333
    334     def _extract_parsed_response(self, response):

/opt/conda/lib/python3.7/site-packages/botocore/client.py in _api_call(self, *args, **kwargs)
    384                     "%s() only accepts keyword arguments." % py_operation_name)
    385             # The "self" in this scope is referring to the BaseClient.
--> 386             return self._make_api_call(operation_name, kwargs)
    387
    388         _api_call.__name__ = str(py_operation_name)

/opt/conda/lib/python3.7/site-packages/botocore/client.py in _make_api_call(self, operation_name, api_params)
    690         else:
    691             http, parsed_response = self._make_request(
--> 692                 operation_model, request_dict, request_context)
    693
    694         self.meta.events.emit(

/opt/conda/lib/python3.7/site-packages/botocore/client.py in _make_request(self, operation_model, request_dict, request_context)
    709     def _make_request(self, operation_model, request_dict, request_context):
    710         try:
--> 711             return self._endpoint.make_request(operation_model, request_dict)
    712         except Exception as e:
    713             self.meta.events.emit(

/opt/conda/lib/python3.7/site-packages/botocore/endpoint.py in make_request(self, operation_model, request_dict)
    100         logger.debug("Making request for %s with params: %s",
    101                      operation_model, request_dict)
--> 102         return self._send_request(request_dict, operation_model)
    103
    104     def create_request(self, params, operation_model=None):

/opt/conda/lib/python3.7/site-packages/botocore/endpoint.py in _send_request(self, request_dict, operation_model)
    130     def _send_request(self, request_dict, operation_model):
    131         attempts = 1
--> 132         request = self.create_request(request_dict, operation_model)
    133         context = request_dict['context']
    134         success_response, exception = self._get_response(

/opt/conda/lib/python3.7/site-packages/botocore/endpoint.py in create_request(self, params, operation_model)
    114                 op_name=operation_model.name)
    115             self._event_emitter.emit(event_name, request=request,
--> 116                                      operation_name=operation_model.name)
    117         prepared_request = self.prepare_request(request)
    118         return prepared_request

/opt/conda/lib/python3.7/site-packages/botocore/hooks.py in emit(self, event_name, **kwargs)
    354     def emit(self, event_name, **kwargs):
    355         aliased_event_name = self._alias_event_name(event_name)
--> 356         return self._emitter.emit(aliased_event_name, **kwargs)
    357
    358     def emit_until_response(self, event_name, **kwargs):

/opt/conda/lib/python3.7/site-packages/botocore/hooks.py in emit(self, event_name, **kwargs)
    226                  handlers.
    227         """
--> 228         return self._emit(event_name, kwargs)
    229
    230     def emit_until_response(self, event_name, **kwargs):

/opt/conda/lib/python3.7/site-packages/botocore/hooks.py in _emit(self, event_name, kwargs, stop_on_response)
    209         for handler in handlers_to_call:
    210             logger.debug('Event %s: calling handler %s', event_name, handler)
--> 211             response = handler(**kwargs)
    212             responses.append((handler, response))
    213             if stop_on_response and response is not None:

/opt/conda/lib/python3.7/site-packages/botocore/signers.py in handler(self, operation_name, request, **kwargs)
     88         # this method is invoked to sign the request.
     89         # Don't call this method directly.
---> 90         return self.sign(operation_name, request)
     91
     92     def sign(self, operation_name, request, region_name=None,

/opt/conda/lib/python3.7/site-packages/botocore/signers.py in sign(self, operation_name, request, region_name, signing_type, expires_in, signing_name)
    158                         signature_version=signature_version)
    159                 else:
--> 160                     raise e
    161
    162             auth.add_auth(request)

/opt/conda/lib/python3.7/site-packages/botocore/signers.py in sign(self, operation_name, request, region_name, signing_type, expires_in, signing_name)
    152                 kwargs['signing_name'] = signing_context['signing_name']
    153             try:
--> 154                 auth = self.get_auth_instance(**kwargs)
    155             except UnknownSignatureVersionError as e:
    156                 if signing_type != 'standard':

/opt/conda/lib/python3.7/site-packages/botocore/signers.py in get_auth_instance(self, signing_name, region_name, signature_version, **kwargs)
    225         if cls is None:
    226             raise UnknownSignatureVersionError(
--> 227                 signature_version=signature_version)
    228         # If there's no credentials provided (i.e credentials is None),
    229         # then we'll pass a value of "None" over to the auth classes,

UnknownSignatureVersionError: Unknown Signature Version: unsigned.

Hi @Ark-kun,
Thanks for reaching out! Boto3 does support public buckets with signed calls (as long as you specify the correct region), but like you pointed out, unsigned calls can be tricky when working with other utilities.  For MLflow, it looks like this is just a matter of importing the UNSIGNED object, which you've addressed in your pull request— I'm not seeing any changes we're able to make here.

Hello, @stobrien89
I've explicitly outlined the problem in the boto3 library and proposed a fix for it.
The problem is that despite the library types, telling the user that only strings are supported, the "unsigned" string does not work.
The solution is pretty simple as well - make the Config class recognize the "unsigned" string.
I'll create a PR for this fix.

Hi @Ark-kun,
Thanks for the clarification.  I'll review with the team to get their thoughts.

@stobrien89 Thank you. I've created a simple fix PR: https://github.com/boto/botocore/pull/2448

@stobrien89 i support this change, as instantiating an AWS airflow connection as UNSIGNED doesn't appear possible at the moment: https://airflow.apache.org/docs/apache-airflow-providers-amazon/stable/connections/aws.html#configuring-the-connection allows you to configure config_kwargs to pass arguments to botore.config.Config, and doing so with:
extra={
  "config_kwargs": {
    "signature_version": botocore.UNSIGNED,
  },
}

results in the error TypeError: Object of type UNSIGNED is not JSON serializable

Thanks for your patience here. I brought up your issue and PR once again with the team, and the consensus was that this they do not plan to do this, the reason being that we cannot support arbitrary strings here and instead rely on strictly defined enums. Also we cannot guarantee compatibility with third-party libraries like MLFlow.


Export do PDF does not create document links

When exporting to PDF from Obsidian the TOC does not appear to be document links in the same way as when making footnotes.

Hi @manfredbjorlin, I've finally got around to looking into this. Just going to do a brain dump.
When Obsidian converts the markdown into HTML, it does not add an ID to the header elements.

In order to link inside a document, the target element needs an ID. That ID becomes the href for the anchor tag. This is clear when you take a look at how footnotes work.

Obsidian generates a unique ID for each footnote, which allows for the link to work.
That being said I could give headers a similar treatment, I'm unsure in the amount of work required.

After much pain, I've discovered it's not possible at the moment.
It's a known issue in Obsidian that same document links aren't functional in PDFs. With the exception of footnotes (for some reason).
Source: https://forum.obsidian.md/t/pdf-export-make-links-within-same-document-functional/16384
In the mean time I'm afraid there isn't much we can do. I'm going to close. I've subscribed to that feature request, if that changes I'll take another look at this.