Commit Graph

7899 Commits

Author SHA1 Message Date
Rafael Mendonça França
8aa8de4991
Merge pull request #51271 from sato11/enable-compact-blank
Enable Hash#compact_blank inside ActiveSupport::LogSubscriber
2024-04-22 18:39:49 -03:00
Rafael Mendonça França
fee72c3aa0
Merge pull request #51640 from Shopify/prepend-to-include
Use `Module#include` rather than `prepend` for faster method lookup
2024-04-22 18:01:08 -03:00
Kevin Menard
8e251a0728 Use Module#include rather than prepend since we don't need prepend semantics here and include leads to faster method lookups. 2024-04-22 16:00:44 -04:00
Earlopain
ea7d3c5165
Deprecate ActiveSupport::ProxyObject
A historic leftover from when Ruby didn't have `BasicObject`
2024-04-22 18:51:38 +02:00
Earlopain
fb886ad464
Remove reference to BlankSlate
This has actually been removed from the builder gem in https://github.com/rails/builder/pull/15
Additionally, `BasicObject` will be more familiar to users.
2024-04-22 15:59:18 +02:00
fatkodima
0883ce1472 Fix ActiveSupport configurations deprecations 2024-04-21 19:36:36 +03:00
Judeeeee
4ac5ee9350 docs: Fix ActiveSupport::TimeWithZone#change example [skip ci]
This Pull Request has been created because the documentation for  `ActiveSupport::TimeWithZone#change` wasn't correct.

The behavior of `:hour` and `:min` is different from the example in the documentation.
I checked with Rails 7.1.3.2 and all digits after nano seconds are 0.

```ruby
t = Time.zone.now   #=> Sat, 20 Apr 2024 14:55:55.688536000 JST +09:00
t.change(hour: 12)  #=> Sat, 20 Apr 2024 12:00:00.000000000 JST +09:00
t.change(min: 30)   #=> Sat, 20 Apr 2024 14:30:00.000000000 JST +09:00
```
2024-04-20 16:12:27 +09:00
Jean Boussier
aa84a783ee ruby-head: handle unused block warnings
Ref: https://bugs.ruby-lang.org/issues/15554

This new Ruby 3.4 warning is still being fined tuned to reduce false positives,
so we shouldn't fail builds on it just yet.

It however caught one mistake in the test suite which is valuable.
2024-04-17 12:24:12 +02:00
Jean Boussier
afa019835b Fix ActiveJob::EnqueueAfterTransactionCommit API
Fix: https://github.com/rails/rails/pull/51426#issuecomment-2042611790

`perform_later` is supposed to return the Job instance on success,
and `false` on error.

When the `enqueue` is automatically delayed, it's of course impossible
to predict if the actual queueing will succeed, but for backward compatibility
reasons, it's best to assume it will.

If necessary, you can hold onto the job instance and check for
`#successfully_enqueued?` after the transaction has completed.
2024-04-10 09:20:12 +02:00
Jean Boussier
cc0f0f9c44 Make ActiveSupport::BacktraceCleaner copy filters and silencers on dup and clone
Previously the copy would still share the internal silencers and filters array,
causing state to leak.
2024-03-29 12:13:32 +01:00
Damian Nelson
9bd8a621f7
Updating Astana with a Western Kazakhstan timezone
On March 1, 2024, Kazakhstan (all parts) switched to use UTC+5. This
updates Astana (captital of Kazakhstan) to use a Western Kazakhstan
TZInfo identifier.
2024-03-12 17:42:16 -07:00
Rosa Gutierrez
71a74ad035
Preserve encoding on truncate_bytes (#51313)
String.new with no arguments returns the empty string with ASCII-8BIT
encoding. Then, depending on each grapheme cluster of the string and
on the omission string, the resulting string might keep the ASCII-8BIT
encoding. With this change, we preserve the encoding of the original
string instead.

Note that String.new accepts an `encoding` keyword argument, like
```
String.new(encoding: Encoding::UTF_8)
```
However, instead of using that, we rely on `force_encoding` to set the
original encoding. This is so that String subclasses don't need to
preserve this keyword argument. For example, SafeBuffer doesn't.
Thanks to @jeremy for catching this!
2024-03-12 15:39:21 -07:00
Junichi Sato
ffbe6050b8
Enable Hash#compact_blank inside ActiveSupport::LogSubscriber
Using ActiveSupport::LogSubscriber#color inside a custom log subscriber
causes NoMethodError.

```ruby
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  gem "activesupport"
end

require "active_support"

class TestLogSubscriber < ActiveSupport::LogSubscriber
  attach_to :test

  def hi(event)
    info(color(event.payload[:message], GREEN))
  end

  private
    def log_exception(name, e)
      super
      raise e
    end
end

ActiveSupport::LogSubscriber.logger = ActiveSupport::Logger.new(STDOUT)
ActiveSupport::Notifications.instrument("hi.test", message: "Hello!")
```

```
/rails/activesupport/lib/active_support/log_subscriber.rb:193:in `mode_from': undefined method `compact_blank' for an instance of Hash (NoMethodError)

      modes = MODES.values_at(*options.compact_blank.keys)
                                      ^^^^^^^^^^^^^^
```

For what it's worth, I have encountered this while using kredis locally, like;

```
$ cd kredis
$ bin/console
irb(main):001> Kredis.string "mystring"
Could not log "meta.kredis" event. NoMethodError: undefined method `compact_blank' for an instance of Hash
```
2024-03-07 10:31:01 +09:00
Rafael Mendonça França
88afcce1dd
Merge pull request #51198 from willnet/fix-wrong-documentation-for-logger_outputs_to
Fix documentation and sample code for `ActiveSupport::Logger.logger_outputs_to?`
2024-02-26 21:08:52 -05:00
Shinichi Maeshima
fc62f03ae3
[ci skip]Fix documentation and sample code for ActiveSupport::Logger.logger_outputs_to?
Fixed incorrect documentation for `ActiveSupport::Logger.logger_outputs_to?`. The method expects the first argument to be a Logger object and subsequent variadic arguments to be either IO objects or strings representing file paths.

Also corrected the sample code in CHANGELOG.md, which previously only passed a single argument, not reflecting the correct usage.

related PR: https://github.com/rails/rails/pull/51125
2024-02-27 10:56:53 +09:00
Rafael Mendonça França
ada3d775bd
Use Kernel#Array to wrap the default value 2024-02-27 01:37:54 +00:00
Rafael Mendonça França
d216d1ede7
Do not always mark the default translation as html safe
If the `_html` suffis isn't provided we should not mark the default
translation as html safe and escape it.
2024-02-27 01:36:40 +00:00
John Hawthorn
0f870c4354 Respect raise_on_missing_ in controller
Previously raise_on_missing_translations was not being respected in a
controller. This commit brings back the correct behaviour.
2024-02-21 13:18:58 -08:00
Rafael Mendonça França
be0661c67a
Merge pull request #51132 from tonytonyjan/docs/fix-fetch-example
Improve the example of ActiveSupport::Cache::Store#fetch
2024-02-20 18:37:44 -05:00
Jian Weihang
a8bc63af54
Improve the example of ActiveSupport::Cache::Store#fetch
The original example has race condition issue that the output of the example isn't conistent, see https://github.com/rails/rails/issues/43588.

The change improves the example by removing unnecessary thread and add detailed comments.

In the new example, there will be race condition only if `ActiveSupport::Cache::MemoryStore` took longer than 0.1 second to extend expiry but that's unlikely to happen.

Close #43588
2024-02-20 12:08:39 +08:00
Christian Schmidt
3aa7d79418 Support filenames in Logger.logger_outputs_to? 2024-02-19 13:39:48 +01:00
Jean Boussier
ca6995a80c Update Method#duplicable? to be consistent with Ruby 3.4
Fix: https://github.com/rails/rails/issues/51075

`Method` and `UnboundMethod` used to raise on `#dup`, but not `#clone`,
this wasn't so much a feature, but a bug.

It was fixed in https://github.com/ruby/ruby/pull/9926.
2024-02-14 09:52:55 +01:00
Rafael Mendonça França
efa8889ad6
Merge pull request #51017 from p8/activesupport/document-time-zone-create
Improve documentation of ActiveSupport::TimeZone.create [ci-skip]
2024-02-09 18:31:27 -05:00
Jean Boussier
7025c84eda Workaround a Ruby bug that can cause a VM crash
See: https://bugs.ruby-lang.org/issues/20250

The bug exist all the way since Ruby 2.7, if you `clone` a `Proc`
object on which you already accessed `object_id`, when its clone
is GCed Ruby will crash.

By accessing the clone's `object_id` right away, we prevent the
crash.
2024-02-09 16:29:46 +01:00
Petrik
15b45953a0 Improve documentation of ActiveSupport::TimeZone.create [ci-skip]
The `create` method is currently marked as an alias of `new`. However,
because `new` is later overridden, it's no longer an alias.

This requires wrapping the `alias_method` with stopdoc/startdoc, as the
method is still marked as an alias otherwise (adding `:nodoc:` doesn't
help).

The `initialize` method has to be wrapped with stopdoc/startdoc as well,
as the `new` method will still be documented for the initialized.
Adding a `:nodoc:` instead will remove documentation for all following
methods.
2024-02-08 21:21:57 +01:00
George Ma
3711c69ab0 Add :: to namespace the module we delegate "to"
Only namespace when the delegation object is a module
2024-01-31 11:35:15 +01:00
Tristan Starck
b0b481a7c4
Fix teardown callbacks (#50915)
* Switch ActiveSupport::TestCase teardown and setup callbacks to run in setup and teardown minitest lifecycle hooks.

Minitest provides `setup` and `teardown` lifecycle hooks to run code in. In general it is best practice to when defining your own test case class, to use `Minitest::TestCase.setup` and `Minitest::TestCase.teardown` instead of `before_setup` and `after_teardown`.

Per Minitest's Documentation on Lifecycle Hooks: https://docs.ruby-lang.org/en/2.1.0/MiniTest/Unit/LifecycleHooks.html
> before_setup()
> Runs before every test, before setup. This hook is meant for libraries to extend minitest. It is not meant to be used by test developers.

> after_teardown()
> Runs after every test, after teardown. This hook is meant for libraries to extend minitest. It is not meant to be used by test developers.

Since the `setup` and `teardown` ActiveSupport::TestCase callbacks are in essence user code, it makes sense to run during their corresponding Minitest Lifecycle hooks.

* Ensure test fixutres are torndown on errors in superclass after_teardown code.

By not adding wrapping the `teardown_fixtures` code, its possible that super raises an error and prevents the existing database transaction from rolling back.
`super` in general should only be calling `Minitest::Testcase.after_teardown` however, if another library were to override `Minitest::Testcase.after_teardown`, like the popular gem [rspec-mocks](https://github.com/rspec/rspec-mocks/blob/main/lib/rspec/mocks/minitest_integration.rb#L23) does, it causes all subsequent tests to retain any changes that were made to the database in the original test that errors.

* Remove unnecessary setup and teardown methods in tests

* update activesupport Changelog

* Fix linter issues in CHANGELOG

* fix tests with improper setup and teardown method definitions

* Fix final CHANGELOG lint

* Revert "Fix final CHANGELOG lint"

This reverts commit f30682eb629780862ccc63e1d3210dfe035e997e.

* Revert "fix tests with improper setup and teardown method definitions"

This reverts commit 1d5b88c8739695a4eed5c46924c9ffc6010353f5.

* Revert "Fix linter issues in CHANGELOG"

This reverts commit 60e89bd189cbcdf50d7e923a90ec5ebe1578a6e9.

* Revert "update activesupport Changelog"

This reverts commit 0f19bc324fec7a793cc34dcfede27017b5a24e46.

* Revert "Remove unnecessary setup and teardown methods in tests"

This reverts commit e5673f179ac01c814ab44017b97e7638aad6e775.

* Revert "Switch ActiveSupport::TestCase teardown and setup callbacks to run in setup and teardown minitest lifecycle hooks."

This reverts commit d08d92d86131d8643a275397d9b0c15995730a14.

* Rescue Minitest::Assertion errors in ActiveSupport::TestCase.teardown callback code to ensure all other after_teardown methods are called.

* Fix name of test class

* remove unused MyError class

* Fix module to not be in global namespace

Co-authored-by: Rafael Mendonça França <rafael@rubyonrails.org>
2024-01-30 19:05:18 -05:00
Jean Boussier
794016aad7 BacktraceCleaner silence core internal methods by default
In recent Ruby versions some pure C functions have been moved into
some semi-ruby code and now have an `<internal:something>` location.

They should be silenced like stdlib etc.
2024-01-30 13:24:50 +01:00
Jean Boussier
8ec5219801 ActiveSupport::Delegation allow to specify the signature
When delegating known APIs, rather that to let Delegator try to
inspect the signature, or to fallback to `...`, we can directly
specify it.

This is both faster and make for nicer delegators that have
the right signature.
2024-01-25 11:51:01 +01:00
Jean Boussier
f760ccd171 ActiveSupport::Delegation optimize self.class delegation
Since `self.class` can't possible be `nil`, we can skip the
useless `nil` checks and generate more efficient code.
2024-01-25 11:51:00 +01:00
Jean Boussier
bffe05f246 Module#delegate stop accepting the private as: parameter
The feature remains usable internally, but via `ActiveSupport::Delegation`,
this way we don't allow third party use.
2024-01-25 11:51:00 +01:00
Jean Boussier
6ee0041ed2 Refactor Module#delegate inside ActiveSupport::Delegation
This allow to support some extra private features without exposing
them in `Module#delegate`.
2024-01-25 11:51:00 +01:00
Jean Boussier
ddc32f5a47 Use an anonymous block parameter in Module#delegate
`...` generates an anonymous block, it's basically a shortcut
for `*, **, &`. So to look more similar to tools that introspect
method signatures, it's best to continue to use an anonymous block.
2024-01-25 09:16:21 +01:00
Petrik de Heus
fe81d667a7
Merge pull request #50789 from p8/docs/relative-includes
Use relative includes of README's in documentation [ci-skip]
2024-01-21 18:30:07 +01:00
m-nakamura145
a5af0a9118
Add example to parts documentation [ci-skip] 2024-01-19 22:05:59 +09:00
Petrik
8565f45100 Use relative includes of README's in documentation [ci-skip]
The Rails documentation uses the `:include:` directive to inline the
README of the framework into the main documentation page. As the
README's aren't in the root directory from where SDoc is run we need to
add the framework path to the include:

    # :include: activesupport/README.md

This results in a warning when installing the gems as generating the rdoc for the gem is run from the gem/framework root:

    Couldn't find file to include 'activesupport/README.rdoc' from lib/active_support.rb

The `:include:` RDoc directive supports includes relative to the current
file as well:

    # :include: ../README.md

This makes sure it works for the Rails API docs and the separate gems.

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2024-01-18 10:39:15 +01:00
Jean Boussier
4530a56e0f RateLimiting Cleanups
Followup: https://github.com/rails/rails/pull/50781

Some small issues I failed to address in the original PR.
2024-01-18 10:11:43 +01:00
Jean Boussier
b54a287f9d Ensure all Cache store have consistent TTL behavior on increment
Make sure they all increment the counter but don't update the TTL.
2024-01-17 15:40:16 +01:00
Jean Boussier
de779f2bf7 Fix ActiveSupport::Notifications.publish_event to preserve units
Ref: https://github.com/rails/rails/pull/43502
Fix: https://github.com/rails/rails/pull/50767
Fix: https://github.com/rails/rails/pull/50493

When republishing a an event into a `start, finish` tuple, we need
to convert the timestamps back into seconds.
2024-01-17 12:53:40 +01:00
Eugene Kenny
0656787be6
Merge pull request #50764 from eugeneius/syntax_error_proxy_nil_backtrace_locations
Handle nil backtrace_locations in SyntaxErrorProxy
2024-01-16 14:20:13 +00:00
Jean Boussier
946e46ebcc Modernize method missing implementations
`...` is both simpler an more correct since the keyword argument
separation.
2024-01-16 13:17:45 +01:00
Eugene Kenny
16d1351a93 Handle nil backtrace_locations in SyntaxErrorProxy 2024-01-16 01:05:53 +00:00
r-plus
38151711c8 Fix IPAddr prefix information missing when write to cache in msgpack serializer
* Save cache size by omit the prefix if unnecessary

* rename to straightforward naming.

* check the prefix directly instead of inspect

* Remove unused helper method

* add to changelog

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2024-01-15 00:40:44 -06:00
Jonathan Hefner
aa98bc3c71 Prevent CurrentAttributes defaults from leaking
Follow-up to #50677.

Prior to this commit, all `ActiveSupport::CurrentAttributes` subclasses
stored their default values in the same `Hash`, causing default values
to leak between classes.  This commit ensures each subclass maintains a
separate `Hash`.

This commit also simplifies the resolution of default values, replacing
the `merge_defaults!` method with `resolve_defaults`.
2024-01-11 12:40:14 -06:00
Jean Boussier
4bded3c00a Module#delegate avoid creating a unique fstring for each delegator
For example:

```ruby
delegate :negative?, to: :value, as: Numeric
```

Before:

```
def negative?(&block)
  _ = @value
  _.negative?(&block)
rescue NoMethodError => e
  if _.nil? && e.name == :negative?
    raise DelegationError, "ActiveSupport::Duration#negative? delegated to @value.negative?, but @value is nil: #{self.inspect}"
  else
    raise
  end
end
```

After:

```ruby
def negative?(&block)
  _ = @value
  _.negative?(&block)
rescue NoMethodError => e
  if _.nil? && e.name == :negative?
    raise DelegationError.nil_target(:negative?, :"@value")
  else
    raise
  end
end
```

Before almost every delegator would generate a large unique string that gets interned for
the error message that is rarely if ever used.

Rather than to "hardcode" a unique string, we now only pass pre-existing symbols to
a method helper that will build the error message.

This alone saves about 160B per delegator, and the method bytecode is also marginally
smaller (but it's harder to assess how much this actually saves)
2024-01-10 19:27:50 +01:00
Jean Boussier
61b48fe76d
Merge pull request #50686 from seanpdoyle/remove-current-attributes-method-missing
Avoid definition of methods at runtime in `CurrentAttributes`
2024-01-10 09:40:09 +01:00
Sean Doyle
c8e5b0b531 Avoid definition of methods in CurrentAttributes at runtime
Replacing on the fly a `method_missing` by a generated method
sound like a nice trick, but it's not as good as it sound for
optimization, as the method will be generated by the first
request to use it, preventing the ISeq from being is shared memory.

Instead we can eagerly define a delegator when instance methods
are defined, and keep a regular `method_missing + send` for the
very rare cases not covered.

Co-Authored-By: Jean Boussier <jean.boussier@gmail.com>
2024-01-10 08:59:35 +01:00
Sean Doyle
d1d6b6bce3 Add default: support for ActiveSupport::CurrentAttributes.attribute
Extend the `.attribute` class method to accept a `:default` option for
its list of attributes:

```ruby
class Current < ActiveSupport::CurrentAttributes
  attribute :counter, default: 0
end
```

Internally, `ActiveSupport::CurrentAttributes` will maintain a
`.defaults` class attribute to determine default values during instance
initialization.
2024-01-09 19:09:57 -05:00
Sean Doyle
2cd4abcc87 Simplify CurrentAttribute.instance delegation
Follow-up to [#50676][]

Instead of relying on code generation, call a corresponding [delegate][]
method on the `.singleton_class`.

[#50676]: https://github.com/rails/rails/pull/50676
[delegate]: https://edgeapi.rubyonrails.org/classes/Module.html#method-i-delegate

Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
2024-01-09 16:54:00 -05:00
Sean Doyle
3c72983dc5 Implement CurrentAttributes#set in terms of Object#with
`CurrentAttributes` supports block-scoped overrides for its attributes
through the `#set` method. The introduction of [CurrentAttributes#set][]
predates the introduction of [Object#with][] by 6 years.

This commit changes the implementation of `#set` to delegate to `#with`.
Through that delegation, the private `#assign_attributes` and
`#compute_attributes` methods are no longer necessary.

[CurrentAttributes#set]: 2d6b02bad6/activesupport/lib/active_support/current_attributes.rb (L210)
[Object#with]: 2d6b02bad6/activesupport/lib/active_support/core_ext/object/with.rb (L26)
2024-01-09 14:34:18 -05:00