Problem/Motivation

\Drupal\Component\Utility\Bytes::toInt() always returns a float. This is because it uses the round() function which always returns a float. The name is misleading because suggests that it returns an integer.

Per the documentation it should return integer value but in fact it always returns float.
https://github.com/drupal/drupal/blob/9.0.0-rc1/core/lib/Drupal/Componen...

Proposed resolution

Rename method Bytes::toInt() to Bytes::toNumber() that always returns a float.
Deprecate \Drupal\Component\Utility\Bytes::toInt() for removal in D10.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

CommentFileSizeAuthor
#82 interdiff-81-82.txt667 bytesjungle
#82 3142934-82.patch14.15 KBjungle
#81 interdiff-79-81.txt2.17 KBjungle
#81 3142934-81.patch14.15 KBjungle
#78 interdiff-74-78.txt9.25 KBjungle
#78 3142934-78.patch13.92 KBjungle
#74 3142934-74.patch4.67 KBjungle
#74 interdiff-67-74.txt2.77 KBjungle
#70 interdiff-67-70.txt1.39 KBjungle
#70 3142934-70.patch0 bytesjungle
#67 interdiff-64-67.txt2.74 KBjungle
#67 3142934-67.patch3.83 KBjungle
#64 interdiff-62-64.txt1.18 KBjungle
#64 3142934-64.patch4.21 KBjungle
#62 interdiff-54-62.txt6.16 KBjungle
#62 3142934-62.patch4.21 KBjungle
#54 interdiff-51-54.txt824 bytesjungle
#54 3142934-54.patch3.31 KBjungle
#51 raw-interdiff-48-51.txt613 bytesjungle
#51 3142934-51.patch3.3 KBjungle
#48 interdiff-47-48.txt755 bytesjungle
#48 3142934-48.patch3.25 KBjungle
#47 3142934-47.patch3.37 KBkrzysztof domański
#47 inteerdiff-44-47.txt295 byteskrzysztof domański
#44 interdiff.3142934.39-44.txt1.12 KBlongwave
#44 3142934-44.patch3.08 KBlongwave
#39 3142934-35.patch2.24 KBkrzysztof domański
#36 3142934-35-test-only.patch986 byteslongwave
#35 interdiff.3142934.29-35.txt829 byteslongwave
#35 3142934-35.patch2.24 KBlongwave
#29 interdiff_17-29.txt1.15 KBmondrake
#29 3142934-29.patch2.76 KBmondrake
#25 interdiff_17-26.txt1.46 KBmondrake
#25 3142934-26.patch3.08 KBmondrake
#17 interdiff_7-17.txt2.32 KBmondrake
#17 3142934-17.patch2.31 KBmondrake
#7 3142934-7.patch1.24 KBsivaji_ganesh_jojodae
#4 3142934-4.patch692 bytessivaji_ganesh_jojodae

Comments

Chi created an issue. See original summary.

jyotimishra-developer’s picture

Hi @Chi,
Hope you will fine!!
I am not getting what needs to be done here? can you pls elaborate, if you dont mind?

mondrake’s picture

In

  /**
   * Parses a given byte size.
   *
   * @param mixed $size
   *   An integer or string size expressed as a number of bytes with optional SI
   *   or IEC binary unit prefix (e.g. 2, 3K, 5MB, 10G, 6GiB, 8 bytes, 9mbytes).
   *
   * @return int
   *   An integer representation of the size in bytes.
   */
  public static function toInt($size) {
    // Remove the non-unit characters from the size.
    $unit = preg_replace('/[^bkmgtpezy]/i', '', $size);
    // Remove the non-numeric characters from the size.
    $size = preg_replace('/[^0-9\.]/', '', $size);
    if ($unit) {
      // Find the position of the unit in the ordered string which is the power
      // of magnitude to multiply a kilobyte by.
      return round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));
    }
    else {
      return round($size);
    }
  }

add a casting to int before returning a value, i.e.

    if ($unit) {
      // Find the position of the unit in the ordered string which is the power
      // of magnitude to multiply a kilobyte by.
      return (int) round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));
    }
    else {
      return (int) round($size);
    }

that's the right fix IMO, we can't do anything else in a method named toInt...

sivaji_ganesh_jojodae’s picture

Status: Active » Needs review
Issue tags: +Needs issue summary update
StatusFileSize
new692 bytes

Patch attached to update the documentation.

mondrake’s picture

Title: Wrong documentation of Bytes::toInt() » Bytes::toInt() always returns a float
Component: other » base system
Issue summary: View changes
Status: Needs review » Needs work
Issue tags: -Needs issue summary update

I definitely struggle on #4 :)

mondrake’s picture

Issue tags: +Needs tests

Also, we need an automated test (or an integration to an existing one?) to ensure we do not incur in regressions.

sivaji_ganesh_jojodae’s picture

Status: Needs work » Needs review
StatusFileSize
new1.24 KB
chi’s picture

add a casting to int before returning a value

Given that Drupal 8+ does not support PHP 5 anymore why not just add int type hint to that method? That would make casting automatically.

mondrake’s picture

#8 that won't be enough as it would just fail badly if the returned value is not int, so the casting is necessary anyway (round() returns a float always). Besides that, adding a typehint is also a bigger problem because any class extending from that would fail miserably at syntax checking - a BC issue.

Status: Needs review » Needs work

The last submitted patch, 7: 3142934-7.patch, failed testing. View results

mondrake’s picture

But... I am afraid here we're hitting another problem, i.e. int are not sufficient for representing zettabytes and yottabytes...

chi’s picture

it would just fail badly

It would not.
https://3v4l.org/PmrWm

a BC issue

That's correct. Though I cannot think of any good reason to extend such a small class with a single static method.

mondrake’s picture

#12 try ‘1 YB’

chi’s picture

#13 That's true, but with explicit casting it returns 0 for '1 YB', which is not much better )

mondrake’s picture

#14 agree. Then we have to make the casting conditional on the result being below PHP_INT_MAX. Below return int, above leave a float. And needs to be documented and tested.

mondrake’s picture

Assigned: Unassigned » mondrake

on this

mondrake’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new2.31 KB
new2.32 KB

Done #15.

mondrake’s picture

Assigned: mondrake » Unassigned
krzysztof domański’s picture

Status: Needs review » Reviewed & tested by the community

In this case, casting data types should be safe. It replaces the rounded float (e.g. 10.0 -> 10).

longwave’s picture

+++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
@@ -28,7 +28,8 @@ class BytesTest extends TestCase {
+    $expected = $expected_int > PHP_INT_MAX ? $expected_int : (int) $expected_int;

This is just copying the code under test, which doesn't make it a very good test. Can we add the type to the data provider somehow? Or at least call assertIsFloat/assertIsInt and go back to assertEquals instead of casting here?

xjm’s picture

Priority: Minor » Normal
Status: Reviewed & tested by the community » Needs work
Issue tags: -Novice

OK, this issue title made me laugh.

I think @longwave raises a good point; NW to look into that.

chi’s picture

Conditional type casting will not make toInt() truly to toInt(). Would it be better just through an exception when rounded value exceeds PHP_INT_MAX?

sivaji_ganesh_jojodae’s picture

Maybe it is better to add another method toLong() or toFloat() for the caller to use in the cases like 1 YB.

+1 for toInt() to thrown an exception if it exceeds PHP_INT_MAX.

mondrake’s picture

Assigned: Unassigned » mondrake

On this.

Throwing an exception here would be a behavior change and hence a BC break... I understand not everybody is uploading zettabyte sized files everyday, but still... :) (that's also a reason IMHO this is a minor issue)

So if we want to do that, we would have to deprecate first, etc. etc.

mondrake’s picture

Assigned: mondrake » Unassigned
Status: Needs work » Needs review
StatusFileSize
new3.08 KB
new1.46 KB

Let's see if this is better, from the test side - force the number literals in the data provider.

sivaji_ganesh_jojodae’s picture

Patch looks visually fine to me but returning float by a method named toInt() doesn't seem contextual. Maybe the method needs renaming?

mondrake’s picture

@Sivaji per Drupal policy we can't just rename a method, unless it's a private one, or marked @internal (and even in those cases I see debate). We would need to add a new toFloat() method instead, deprecate toInt(), and file a follow-up to remove in D10. But that would be a separate issue IMHO. Again, I think 99.999999% of the cases we never really get to convert ZB or YB in real life.

mondrake’s picture

Assigned: Unassigned » mondrake
Status: Needs review » Needs work

So in #25 we learn that large literal numbers cannot be parsed if above PHP_INT_MAX... interesting. Working out something different.

mondrake’s picture

Assigned: mondrake » Unassigned
Status: Needs work » Needs review
StatusFileSize
new2.76 KB
new1.15 KB

Following @longwave suggestion in #20.

sivaji_ganesh_jojodae’s picture

@mondrake, agreed.

Can I create a new issue to add a new method & deprecate the toInt() in D10?

I suggest naming it to toByte() to allow returning int or float as needed.

mondrake’s picture

@Sivaji sure thing! Everybody can, this is the sense of open source :)

longwave’s picture

I meant something more like

  public function testToInt($size, $expected_int) {
    $value = Bytes::toInt($size);
    $this->assertEquals($expected_int, $value);
    if ($expected_int > PHP_INT_MAX) {
      $this->assertIsFloat($value);
    }
    else {
      $this->assertIsInt($value);
    }      
  }

Can we assume we are always testing on 64 bit systems (in which case we know for sure which test cases will be float and which will be int), or is that too much of an assumption to make?

mondrake’s picture

#32 AFAIK assertSame also checks the type, so isn't that superflous?
Also about 64-bit I think that's too strong an assumption - fair enough on DrupalCI will be like that, but locally not.

Maybe we can use PHP_INT_SIZE in the test data provider and make the list of expected return values dependent on that, instead: https://stackoverflow.com/questions/670662/whats-the-maximum-value-for-a...

OTOH I'm afraid on 32-bit the parsing will fail for 64-bit only number literals, same way as in #25 the number 1180591620717411303424, which is 1 ZB, fails even on 64-bit.

longwave’s picture

Actually, can we simply use assertSame without casting at all in the test?

php > print PHP_INT_MAX;
9223372036854775807
php > print gettype(pow(1024, 6));
integer
php > print gettype(pow(1024, 7));
double
longwave’s picture

StatusFileSize
new2.24 KB
new829 bytes
longwave’s picture

StatusFileSize
new986 bytes

Status: Needs review » Needs work

The last submitted patch, 36: 3142934-35-test-only.patch, failed testing. View results

mondrake’s picture

Status: Needs work » Needs review

Nice and clean, @longwave!

RTBC +1, but I cannot.

krzysztof domański’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new2.24 KB

1. It looks good to me too. Attaching fix patch (#35) as the latest attachment to be tested by the bot (retested daily).

2. In this case, casting data types should be safe. It always replaces the rounded float (e.g. 10.0 -> 10).

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 39: 3142934-35.patch, failed testing. View results

krzysztof domański’s picture

Status: Needs work » Reviewed & tested by the community

Random test failure.

xjm’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/lib/Drupal/Component/Utility/Bytes.php
    @@ -32,11 +33,12 @@ public static function toInt($size) {
    -      return round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));
    +      $result = round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));
    

    I haven't read this code in a really long time but am struck again that bkmgtpezy sounds like a made-up creature in childrens' literature à la Lewis Carroll. "All mimsy were the bkmgtpezy, and the mome raths outgrabe."

  2. --- a/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
    +++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
    @@ -17,10 +17,10 @@ class BytesTest extends TestCase {
    -   * @param int $expected_int
    +   * @param int|float $expected_int
    
    @@ -28,7 +28,7 @@ class BytesTest extends TestCase {
    -    $this->assertEquals($expected_int, Bytes::toInt($size));
    +    $this->assertSame($expected_int, Bytes::toInt($size));
    

    Shouldn't we be testing both types of return now -- int and float? The data provider is all int-y return things. We're solving part of the test coverage problem with the assertSame() but not all of it I think. It could be just one more case with a SRSLY LARGE NUMBER in the data provider.

Looks good other than that; I think we came 'round to a good place. Thanks!

longwave’s picture

As demonstrated in #34, zettabytes and yottabytes don't fit in a 64 bit int and the pow() function automatically returns a float (double) for these. assertSame checks the type which ensures our method also returns int for the smaller sizes and float for the larger ones. Maybe we need a comment to this effect though?

longwave’s picture

Status: Needs work » Needs review
StatusFileSize
new3.08 KB
new1.12 KB

Added some explanatory comments.

mondrake’s picture

Status: Needs review » Reviewed & tested by the community

I think this is the maximum we can do with a method called toInt that has to handle non-ints. A follow up could be to deprecate this method in favour of a, say, toNumber method always returning a float.

xjm’s picture

Status: Reviewed & tested by the community » Needs work

That works for me.

Turns out, we need to add the words zettabyte and zettabytes to core's dictionary for the spellchecking we just added. (Oddly enough, "yottabytes" is already there.)

krzysztof domański’s picture

Version: 9.0.x-dev » 9.1.x-dev
Status: Needs work » Needs review
StatusFileSize
new295 bytes
new3.37 KB
jungle’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new3.25 KB
new755 bytes
+++ b/core/misc/cspell/dictionary.txt
@@ -2249,6 +2249,8 @@ yygroup
+zettabyte
+zettabytes

After running the spellcheck commands on my local, found out we only need to add zettabytes. 1) As yottabytes is not a unknown word, I think that it's better to have zettabytes added to a upstream dictionary. 2) Meanwhile, we are in progress of removing typos/words from the dictionary file, so I tend to ignore it by using cspell:ignore, not adding it to the dictionary.

Attached patch ignored zettabytes. I did run an extra spellcheck on my local, it works. So setting this to RTBC at the same time, as the patch is less than 1KB.

$ yarn run spellcheck:core
yarn run v1.22.4
$ cspell "**/*" "../composer/**/*" "../composer.json"
CSpell: Files checked: 14653, Issues found: 0 in 0 files
✨  Done in 234.63s.
alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Needs a reroll.

mondrake’s picture

jungle’s picture

Status: Needs work » Needs review
StatusFileSize
new3.3 KB
new613 bytes

Rerolled and replaced pow() with the ** operator

+++ b/core/lib/Drupal/Component/Utility/Bytes.php
@@ -32,11 +33,12 @@ public static function toInt($size) {
+      $result = round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));
In PHP 5.6 onwards, you may prefer to use the ** operator.

See https://www.php.net/manual/en/function.pow.php

mondrake’s picture

+++ b/core/lib/Drupal/Component/Utility/Bytes.php
@@ -32,12 +33,13 @@ public static function toInt($size) {
+      $result = round($size * (self::KILOBYTE ** stripos('bkmgtpezy', $unit[0])));
...
+      $result = round($size);

I think we'll have to cast $size to float here, since that was done in #3156879: \Drupal\Component\Utility\Bytes::toInt() - ensure $size is a number type and is probably the reason this needed a reroll.

longwave’s picture

> replaced pow() with the ** operator

Why? We don't use ** anywhere else in core that I can see, we do use pow(), and (personal opinion) pow() is much easier to read and remember what it does.

jungle’s picture

StatusFileSize
new3.31 KB
new824 bytes
  1. #52, thanks @mondrake, I did not notice that.
  2. #53, just preference, reverted.
krzysztof domański’s picture

Status: Needs review » Reviewed & tested by the community

Looks good, back to RTBC.

mondrake’s picture

alexpott’s picture

Category: Bug report » Task
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs change record

I don't think this is a bug per se - it's certainly unexpected given the name but it has been this way for years. Given we are subtly changing the return type I think we should have a change record - in the very unlikely case that someone is depending on this returning a float.

krzysztof domański’s picture

I don't think this is a bug per se - it's certainly unexpected given the name but it has been this way for years. (...) in the very unlikely case that someone is depending on this returning a float.

The reason for this problem is the misleading name, not the return type so #4 is safer (backwards compatibility).

-   * @return int
-   *   An integer representation of the size in bytes.
+   * @return float
+   *   The floating point value of the size in bytes.
    */
   public static function toInt($size) {

Let's change documentation and deprecate the Bytes::toInt() method.
#3143478: Rename method Bytes::toInt() to Bytes::toNumber()

jungle’s picture

Status: Needs work » Needs review

If so, I would suggest re-scoping here to include #3143478: Rename method Bytes::toInt() to Bytes::toNumber().


  /**
   * Parses a given byte size.
   *
   * @param mixed $size
   *   An integer or string size expressed as a number of bytes with optional SI
   *   or IEC binary unit prefix (e.g. 2, 3K, 5MB, 10G, 6GiB, 8 bytes, 9mbytes).
   *
   * @return int|float
   *   An integer representation of the size in bytes. If the size is larger
   *   than PHP_INT_MAX, then the returned value is a float.
   */
  public static function toNumber($size) {
    $result = self::toInt($size);
    return $result > PHP_INT_MAX ? $result : (int) $result;
  }

Add toNumber(), keep toInt() untouched and deprecate it.

Set back to NR for suggestions of what to do next.

mondrake’s picture

+1 on #59. We should close the other one as duplicate then.

krzysztof domański’s picture

   * @return int|float
   *   An integer representation of the size in bytes. If the size is larger
   *   than PHP_INT_MAX, then the returned value is a float.
   */
  public static function toNumber($size) {

Re #59. IMO toNumber is a suitable name. Dependency on PHP_INT_MAX is not good. Better if it always returns float.

 * @return float
 *   The floating point value of the size in bytes.
 */
public static function toNumber($size) {
jungle’s picture

StatusFileSize
new4.21 KB
new6.16 KB

Thanks @mondrake and @Krzysztof Domański!

  1. Did as #59, but toNumber() returns a float as suggested in #61.
  2. CR added. https://www.drupal.org/node/3162663
jungle’s picture

Status: Needs review » Needs work
+++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
@@ -62,4 +67,57 @@ public function providerTestToInt() {
+   * @param int|float $expected_int
...
+  public function testToNumber($size, $expected_int) {
+    $this->assertSame($expected_int, Bytes::toNumber($size));

Self review:

int|float -> float, expected_int -> expected_number

jungle’s picture

Issue tags: -Needs change record
StatusFileSize
new4.21 KB
new1.18 KB
  1. BTW
    +++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
    @@ -62,4 +67,57 @@ public function providerTestToInt() {
    +   * @group legacy
    ...
    +  public function testToNumber($size, $expected_int) {
    
    Only tests with the `@group legacy` annotation can expect a deprecation.

    So that @group legacy added to testToNumber() as well.

  2. Addressing #63
jungle’s picture

Status: Needs work » Needs review
krzysztof domański’s picture

Status: Needs review » Needs work

We will remove the Bytes::toInt() method in D10 so it should be like this:

public static function toInt($size) {
  @trigger_error('\Drupal\Component\Utility\Bytes::toInt() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Component\Utility\Bytes::toNumber() instead. See https://www.drupal.org/node/3162663', E_USER_DEPRECATED);
  return self::toNumber($size);
}
public static function toNumber($size) {
  // Remove the non-unit characters from the size.
  $unit = preg_replace('/[^bkmgtpezy]/i', '', $size);
  // Remove the non-numeric characters from the size.
  $size = preg_replace('/[^0-9\.]/', '', $size);
  if ($unit) {
    // Find the position of the unit in the ordered string which is the power
    // of magnitude to multiply a kilobyte by.
    return round($size * pow(self::KILOBYTE, stripos('bkmgtpezy', $unit[0])));
  }
  else {
    // Ensure size is a proper number type.
    return round((float) $size);
  }
}
jungle’s picture

Status: Needs work » Needs review
StatusFileSize
new3.83 KB
new2.74 KB

Thanks @Krzysztof Domański for the review.

Adjusted following #66

andypost’s picture

  1. +++ b/core/lib/Drupal/Component/Utility/Bytes.php
    @@ -25,6 +25,21 @@ class Bytes {
    +   * @param mixed $size
    +   *   An integer or string size expressed as a number of bytes with optional SI
    +   *   or IEC binary unit prefix (e.g. 2, 3K, 5MB, 10G, 6GiB, 8 bytes, 9mbytes).
    ...
    +  public static function toNumber($size) {
    

    If it accepts int|string then why it can't accept floats?

    Also numeric strings could be used to pass integers which are bigger then PHP_INT_MAX and converted internally by PHP itself

  2. +++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
    @@ -62,4 +67,54 @@ public function providerTestToInt() {
    +      ['2.4', 2.0],
    +      ['', 0.0],
    

    Please add `9223372036854775807` as string

andypost’s picture

+++ b/core/lib/Drupal/Component/Utility/Bytes.php
@@ -25,6 +25,21 @@ class Bytes {
+   * @param mixed $size

mixed is bad practice, better use string|int|float so when core will require PHP 8 we can use union types

jungle’s picture

StatusFileSize
new0 bytes
new1.39 KB

@andypost, thanks for the review!

Addressing #68 and #69

krzysztof domański’s picture

Bytes::toInt() returns Bytes::toNumber() so providerTestToInt() is no longer needed.

--- a/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
@@ -5,6 +5,8 @@
...
    *
-   * @dataProvider providerTestToInt
+   * @dataProvider providerTestToNumber
    * @covers ::toInt
    *
    * @group legacy
    * @expectedDeprecation \Drupal\Component\Utility\Bytes::toInt() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Component\Utility\Bytes::toNumber() instead. See https://www.drupal.org/node/3162663
    */
   public function testToInt($size, $expected_int) {
     $this->assertEquals($expected_int, Bytes::toInt($size));
   }
mondrake’s picture

@jungle something went wrong with your latest patch :(

mondrake’s picture

Status: Needs review » Needs work
jungle’s picture

Status: Needs work » Needs review
StatusFileSize
new2.77 KB
new4.67 KB

Re #72, yes, it's a 0 bytes patch 🤦

Started from #67, addressed #68, #69, #71.

Thanks!

Status: Needs review » Needs work

The last submitted patch, 74: 3142934-74.patch, failed testing. View results

krzysztof domański’s picture

Title: Bytes::toInt() always returns a float » Deprecate \Drupal\Component\Utility\Bytes::toInt() due to return type
Issue summary: View changes
Issue tags: -Needs issue summary update
krzysztof domański’s picture

Issue summary: View changes

Replace calls to toInt() with toNumber(). For example:

--- a/core/lib/Drupal/Component/Utility/Environment.php
+++ b/core/lib/Drupal/Component/Utility/Environment.php
@@ -34,7 +34,7 @@ public static function checkMemoryLimit($required, $memory_limit = NULL) {
     // - The memory limit is set to unlimited (-1).
     // - The memory limit is greater than or equal to the memory required for
     //   the operation.
-    return ((!$memory_limit) || ($memory_limit == -1) || (Bytes::toInt($memory_limit) >= Bytes::toInt($required)));
+    return ((!$memory_limit) || ($memory_limit == -1) || (Bytes::toNumber($memory_limit) >= Bytes::toNumber($required)));
   }
jungle’s picture

Status: Needs work » Needs review
StatusFileSize
new13.92 KB
new9.25 KB

Thanks @Krzysztof Domański!

Addressing #77

mondrake’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Component/Utility/Bytes.php
    @@ -25,6 +25,22 @@ class Bytes {
       public static function toInt($size) {
    +    @trigger_error('\Drupal\Component\Utility\Bytes::toInt() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use \Drupal\Component\Utility\Bytes::toNumber() instead. See https://www.drupal.org/node/3162663', E_USER_DEPRECATED);
    +    return self::toNumber($size);
    +  }
    

    Need to add @deprecated and @see to the docblock.

  2. +++ b/core/lib/Drupal/Component/Utility/Bytes.php
    @@ -25,6 +25,22 @@ class Bytes {
    +  public static function toNumber($size) {
    

    : float return typehint can be added now

  3. +++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
    @@ -24,41 +26,66 @@ class BytesTest extends TestCase {
    +  public function testToNumber($size, $expected_number) {
    

    testToNumber($size, float $expected_number): void

  4. +++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
    @@ -24,41 +26,66 @@ class BytesTest extends TestCase {
    +  public function providerTestToNumber() {
    

    : array return typehint

krzysztof domański’s picture

#79.2 Unfortunately we should not add return typehint to Bytes::toNumber(). Bytes::toInt() inherits Bytes::toNumber().

Ignore.

jungle’s picture

Status: Needs work » Needs review
StatusFileSize
new14.15 KB
new2.17 KB

Thanks @mondrake!

Addressing #79

jungle’s picture

StatusFileSize
new14.15 KB
new667 bytes
+++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
@@ -61,7 +61,7 @@ public function testToNumber($size, $expected_number) {
+  public function providerTestToNumber(): array{

One CS violation, fixing.

krzysztof domański’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @jungle!

mondrake’s picture

+++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
@@ -24,41 +26,66 @@ class BytesTest extends TestCase {
+      // Zettabytes and yottabytes cannot be represented by integers on 64-bit
+      // systems, so pow() returns a float.
       ['1 ZB'  , pow(Bytes::KILOBYTE, 7)],
       ['1 YB'  , pow(Bytes::KILOBYTE, 8)],

nit: the comment here comes from previous patches - not sure it is relevant anymore. Maybe just cast to float as the lines above for consistency.

catch’s picture

Title: Deprecate \Drupal\Component\Utility\Bytes::toInt() due to return type » Rename \Drupal\Component\Utility\Bytes::toInt() to \Drupal\Component\Utility\Bytes::toNumber() due to return type
+++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
@@ -24,41 +26,66 @@ class BytesTest extends TestCase {
+      [1.5, 2.0],

If the new ::toNumber() method does exactly the same as the old one, then why does the test coverage change? Is this just because we were using assertSame() before which is more permissive?

Re-titling since we're essentially renaming with a bc layer, rather than deprecating in favour of an existing alternative.

jungle’s picture

  1. Re #85

    +++ b/core/tests/Drupal/Tests/Component/Utility/BytesTest.php
    @@ -24,41 +26,66 @@ class BytesTest extends TestCase {
         $this->assertEquals($expected_int, Bytes::toInt($size));
    ...
    +    $this->assertSame($expected_number, Bytes::toNumber($size));
    

    Previously, using assertEquals(), now using assertSame()

    • $this->assertEquals(1, 1.0); // Pass
    • $this->assertSame(1, 1.0); // Fail

    So that changed the data provider.

  2. Re-titling since we're essentially renaming with a bc layer, rather than deprecating in favour of an existing alternative.

    From my understanding, I think we should change the title back. the old one (toInt()) is deprecated in favor of the new one (toNumber()), it's not renaming.

Thanks!

catch’s picture

Title: Rename \Drupal\Component\Utility\Bytes::toInt() to \Drupal\Component\Utility\Bytes::toNumber() due to return type » Replace \Drupal\Component\Utility\Bytes::toInt() with \Drupal\Component\Utility\Bytes::toNumber() due to return type

#1 makes sense and seems in scope to correct the tests to be inline with the documentation fix here.

Howabout 'replace'? Just trying to summarize the actual change more in the title.

jungle’s picture

Howabout 'replace'? Just trying to summarize the actual change more in the title.

Sounds good. Thanks!

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 7567d54 and pushed to 9.1.x. Thanks!

  • alexpott committed 7567d54 on 9.1.x
    Issue #3142934 by jungle, mondrake, longwave, Krzysztof Domański,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.