Hi internals,
I would like to clarify how attributes are supposed to interact with
strict_types. Consider the following code, split up into three files to
make it clear that each one could have their own strict_types mode:
MyAttribute.php
<?php
#[Attribute]
class MyAttribute {
public function __construct(string $a) {}
}
UseOfMyAttribute.php
<?php
declare(strict_types=1);
#[MyAttribute(42)]
class Test {}
AccessOfAttribute.php
<?php
var_dump((new
ReflectionClass(Test::class'))->getAttributes()[0]->newInstance());
Currently, what happens is that this code will construct the attribute,
converting int 42 into string "42", even though UseOfMyAttribute.php has
strict_types=1.
My intuitive expectation here would be that we should be following the
strict_types mode of wherever the attribute is being used (i.e.
UseOfMyAttribute.php, not MyAttribute.php or AccessOfAttribute.php).
Currently, we always assume strict_types=0.
Is my expectation correct?
Regards,
Nikita
Hi Nikita
From a userland point of view, I'd indeed expect this example to use strict_types, because it's declared in UseOfMyAttribute.php. Is this something that can be changed still?
Kind regards
Brent
Hi internals,
I would like to clarify how attributes are supposed to interact with
strict_types. Consider the following code, split up into three files to
make it clear that each one could have their own strict_types mode:MyAttribute.php
<?php
#[Attribute]
class MyAttribute {
public function __construct(string $a) {}
}UseOfMyAttribute.php
<?php
declare(strict_types=1);
#[MyAttribute(42)]
class Test {}AccessOfAttribute.php
<?php
var_dump((new
ReflectionClass(Test::class'))->getAttributes()[0]->newInstance());Currently, what happens is that this code will construct the attribute,
converting int 42 into string "42", even though UseOfMyAttribute.php has
strict_types=1.My intuitive expectation here would be that we should be following the
strict_types mode of wherever the attribute is being used (i.e.
UseOfMyAttribute.php, not MyAttribute.php or AccessOfAttribute.php).
Currently, we always assume strict_types=0.Is my expectation correct?
Regards,
Nikita
Hi internals,
I would like to clarify how attributes are supposed to interact with
strict_types. Consider the following code, split up into three files to
make it clear that each one could have their own strict_types mode:MyAttribute.php
<?php
#[Attribute]
class MyAttribute {
public function __construct(string $a) {}
}UseOfMyAttribute.php
<?php
declare(strict_types=1);
#[MyAttribute(42)]
class Test {}AccessOfAttribute.php
<?php
var_dump((new
ReflectionClass(Test::class'))->getAttributes()[0]->newInstance());Currently, what happens is that this code will construct the attribute,
converting int 42 into string "42", even though UseOfMyAttribute.php has
strict_types=1.My intuitive expectation here would be that we should be following the
strict_types mode of wherever the attribute is being used (i.e.
UseOfMyAttribute.php, not MyAttribute.php or AccessOfAttribute.php).
Currently, we always assume strict_types=0.Is my expectation correct?
Regards,
Nikita
I could see an argument for either UseOfMyAttribute.php or AccessOfAttribute.php. I think I would also favor UseOfMyAttribute.php, however, because if you get it wrong the place you have to change it is in that file, so it should obey the setting in that file.
--Larry Garfield
I'd expect it to obey the strict_types declaration of UseOfMyAttribute.php,
too. I see it as being where the attribute's constructor is "called", even
though the actual object instantiation happens somewhere else.
— Benjamin
Hi internals,
I would like to clarify how attributes are supposed to interact with
strict_types. Consider the following code, split up into three files to
make it clear that each one could have their own strict_types mode:MyAttribute.php
<?php
#[Attribute]
class MyAttribute {
public function __construct(string $a) {}
}UseOfMyAttribute.php
<?php
declare(strict_types=1);
#[MyAttribute(42)]
class Test {}AccessOfAttribute.php
<?php
var_dump((new
ReflectionClass(Test::class'))->getAttributes()[0]->newInstance());Currently, what happens is that this code will construct the attribute,
converting int 42 into string "42", even though UseOfMyAttribute.php has
strict_types=1.My intuitive expectation here would be that we should be following the
strict_types mode of wherever the attribute is being used (i.e.
UseOfMyAttribute.php, not MyAttribute.php or AccessOfAttribute.php).
Currently, we always assume strict_types=0.Is my expectation correct?
Regards,
NikitaI could see an argument for either UseOfMyAttribute.php or
AccessOfAttribute.php. I think I would also favor UseOfMyAttribute.php,
however, because if you get it wrong the place you have to change it is in
that file, so it should obey the setting in that file.--Larry Garfield
--
To unsubscribe, visit: https://www.php.net/unsub.php
Hi internals,
I would like to clarify how attributes are supposed to interact with
strict_types. Consider the following code, split up into three files to
make it clear that each one could have their own strict_types mode:MyAttribute.php
<?php
#[Attribute]
class MyAttribute {
public function __construct(string $a) {}
}UseOfMyAttribute.php
<?php
declare(strict_types=1);
#[MyAttribute(42)]
class Test {}AccessOfAttribute.php
<?php
var_dump((new
ReflectionClass(Test::class'))->getAttributes()[0]->newInstance());Currently, what happens is that this code will construct the attribute,
converting int 42 into string "42", even though UseOfMyAttribute.php has
strict_types=1.My intuitive expectation here would be that we should be following the
strict_types mode of wherever the attribute is being used (i.e.
UseOfMyAttribute.php, not MyAttribute.php or AccessOfAttribute.php).
Currently, we always assume strict_types=0.Is my expectation correct?
Regards,
Nikita
As we seem to have an agreement that strict_types of UseOfMyAttribute.php
should be respected, I've created an implementation for this at
https://github.com/php/php-src/pull/6201.
Partway through I realized that the root problem is really that we want the
constructor call to happen "as if" it was caused by the use-site of the
attribute. This affects not just strict_types=1, but also backtrace and
error information. In particular, this means that the backtrace now also
points you to which attribute use-site resulted in an exception, which
seems like rather useful information to have, as the same attribute might
be used in many places.
This does mean we have to store the line number of the attribute
internally. We could also expose that information via ReflectionAttribute
now, if we wanted.
Regards,
Nikita
I would like to clarify how attributes are supposed to interact with
strict_types. Consider the following code, split up into three files to
make it clear that each one could have their own strict_types mode:MyAttribute.php
<?php
#[Attribute]
class MyAttribute {
public function __construct(string $a) {}
}UseOfMyAttribute.php
<?php
declare(strict_types=1);
#[MyAttribute(42)]
class Test {}AccessOfAttribute.php
<?php
var_dump((new
ReflectionClass(Test::class'))->getAttributes()[0]->newInstance());Currently, what happens is that this code will construct the attribute,
converting int 42 into string "42", even though UseOfMyAttribute.php has
strict_types=1.My intuitive expectation here would be that we should be following the
strict_types mode of wherever the attribute is being used (i.e.
UseOfMyAttribute.php, not MyAttribute.php or AccessOfAttribute.php).
Currently, we always assume strict_types=0.Is my expectation correct?
I would say that your expectation is correct, and I'm willing to call the
current behavior a bug. No need to worry about FF here.
-Sara