Skip Menu |
Report information
Id: 132425
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: eda [at] waniasset.com
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: low
Type: unknown
Perl Version: (no value)
Fixed In: (no value)



Subject: Suggested warning on attempt to 'use' with arguments when no import() subroutine exists
Date: Fri, 10 Nov 2017 12:27:12 +0000
From: Ed Avis <eda [...] waniasset.com>
To: "'perlbug [...] perl.org'" <perlbug [...] perl.org>
Download (untitled) / with headers
text/plain 7.5k
Download (untitled) / with headers
text/html 15.4k

Message body is not shown because it is too large.

RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 7.6k
The bug tracker ate the message text, or at least refuses to show it on the web page, so here it is: If a module doesn't define an import subroutine, but the caller tries to 'use' that module specifying an import list, this should generate a warning. For example % echo 'package A; sub foo {}; 1;' >A.pm % perl -wE 'use A qw(foo)' This should print something like You asked to import 'foo' from package A, but that package does not define an import() subroutine, so nothing has been imported. Of course, if the module uses Exporter or some other code, that will handle all the cases of generating warnings for things that aren't exported. I am talking only about the case when - the module does not define any import() subroutine, and - the caller has provided extra arguments in the 'use' call. Since those extra arguments are useless, and quite likely indicate some confusion of the programmer, they should trigger a warning. --- Flags: category=core severity=low --- Site configuration information for perl 5.22.2: Configured by Red Hat, Inc. at Fri Nov 4 14:35:02 UTC 2016. Summary of my perl5 (revision 5 version 22 subversion 2) configuration: Platform: osname=linux, osvers=4.7.9-200.fc24.x86_64, archname=x86_64-linux-thread-multi uname='linux buildvm-12.phx2.fedoraproject.org 4.7.9-200.fc24.x86_64 #1 smp thu oct 20 14:26:16 utc 2016 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=none -Dccflags=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Dldflags=-Wl,-z,relro -Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro -Dlddlflags=-shared -Wl,-z,relro -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.22.2 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize=' -g', cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include' ccversion='', gccversion='5.3.1 20160406 (Red Hat 5.3.1-6)', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc', ldflags ='-Wl,-z,relro -fstack-protector-strong -L/usr/local/lib' libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib /lib/../lib64 /usr/lib/../lib64 /lib libs=-lpthread -lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat perllibs=-lpthread -lresolv -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.22.so, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.22' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro ' cccdlflags='-fPIC', lddlflags='-shared -Wl,-z,relro -L/usr/local/lib -fstack-protector-strong' Locally applied patches: Fedora Patch1: Removes date check, Fedora/RHEL specific Fedora Patch3: support for libdir64 Fedora Patch4: use libresolv instead of libbind Fedora Patch5: USE_MM_LD_RUN_PATH Fedora Patch6: Skip hostname tests, due to builders not being network capable Fedora Patch7: Dont run one io test due to random builder failures Fedora Patch15: Define SONAME for libperl.so Fedora Patch16: Install libperl.so to -Dshrpdir value Fedora Patch22: Document Math::BigInt::CalcEmu requires Math::BigInt (CPAN RT#85015) Fedora Patch26: Make *DBM_File desctructors thread-safe (RT#61912) Fedora Patch27: Make PadlistNAMES() lvalue again (CPAN RT#101063) Fedora Patch28: Make magic vtable writable as a work-around for Coro (CPAN RT#101063) Fedora Patch29: Fix duplicating PerlIO::encoding when spawning threads (RT#31923) Fedora Patch30: Do not let XSLoader load relative paths (CVE-2016-6185) Fedora Patch31: Avoid loading optional modules from default . (CVE-2016-1238) Fedora Patch32: Fix a crash in lexical scope warnings (RT#128597) Fedora Patch33: Do not mangle errno from failed socket calls (RT#128316) Fedora Patch34: Fix crash in "evalbytes S" (RT#129196) Fedora Patch35: Fix crash in "evalbytes S" (RT#129196) Fedora Patch36: Fix crash in "evalbytes S" (RT#129196) Fedora Patch37: Fix crash in splice (RT#129164, RT#129166, RT#129167) Fedora Patch38: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267) Fedora Patch39: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267) Fedora Patch40: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267) Fedora Patch41: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267) Fedora Patch42: Fix string overrun in Perl_gv_fetchmethod_pvn_flags (RT#129267) Fedora Patch43: Fix crash when matching UTF-8 string with non-UTF-8 substrings (RT#129350) Fedora Patch44: Fix parsing perl options in shell bang line (RT#129336) Fedora Patch45: Fix firstchar bitmap under UTF-8 with prefix optimization (RT#129950) Fedora Patch46: Avoid infinite loop in h2xs tool if enum and type have the same name (RT130001) Fedora Patch47: Fix stack handling when calling chdir without an argument (RT#129130) Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux --- @INC for perl 5.22.2: /home/eda/lib64/perl5/ /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 --- Environment for perl 5.22.2: HOME=/home/eda LANG=en_GB.UTF-8 LANGUAGE (unset) LC_COLLATE=C LC_CTYPE=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 LC_MONETARY=en_GB.UTF-8 LC_NUMERIC=en_GB.UTF-8 LC_TIME=en_GB.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/eda/bin:/home/eda/bin:/home/eda/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/sbin:/home/eda/.local/bin:/home/eda/bin:/sbin:/usr/sbin:/sbin:/usr/sbin PERL5LIB=/home/eda/lib64/perl5/ PERL_BADLANG (unset) SHELL=/bin/bash
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 222b
On Fri, 10 Nov 2017 04:33:52 -0800, eda@waniasset.com wrote: Show quoted text
> If a module doesn't define an import subroutine
But every module gets an import subroutine: if not their own, their parent's (and at least UNIVERSAL's). Hugo
Subject: Re: [perl #132425] Suggested warning on attempt to 'use' with arguments when no import() subroutine exists
Date: Sat, 11 Nov 2017 10:43:42 +0000
From: Zefram <zefram [...] fysh.org>
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 542b
Hugo van der Sanden via RT wrote: Show quoted text
>But every module gets an import subroutine: if not their own, their >parent's (and at least UNIVERSAL's).
No, UNIVERSAL doesn't contain an import method. There's specific logic in the method calling mechanism that provides what amounts to an empty method if "import" or "unimport" is being looked up and there isn't any actual method, but ->can can see the lack of a method: $ perl -lwe 'print "main"->can("import") // "no method"; print eval { "main"->import; 1 } ? "ok" : "fail"' no method ok -zefram
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.2k
On Sat, 11 Nov 2017 02:44:01 -0800, zefram@fysh.org wrote: Show quoted text
> Hugo van der Sanden via RT wrote:
> > But every module gets an import subroutine: if not their own, their > > parent's (and at least UNIVERSAL's).
> > No, UNIVERSAL doesn't contain an import method. There's specific logic > in the method calling mechanism that provides what amounts to an empty > method if "import" or "unimport" is being looked up and there isn't any > actual method, but ->can can see the lack of a method: > > $ perl -lwe 'print "main"->can("import") // "no method"; print eval { > "main"->import; 1 } ? "ok" : "fail"' > no method > ok
That looks hard to distinguish from 'has an import method, but can() lies about it'. :) But in any case the answer changes if anything has loaded UNIVERSAL: % perl -MUNIVERSAL -lwe 'print "main"->can("import") // "no method"; print eval { "main"->import(1); 1 } ? "ok" : "fail"' CODE(0x1561678) ok % For Ed's original suggestion: if we can reliably detect that there's no explicit import() in the inheritance chain, the suggestion of warning on a useless import arg seems valid, but the above suggests to me that the result would vary depending on whether UNIVERSAL had been loaded, which would at best make it less useful and at worst invalidate the idea. Hugo
Download (untitled) / with headers
text/plain 526b
Wouldn't the answer be to also tweak UNIVERSAL::import? It could be something like sub import { return unless @_ > 1; require Carp; if ($_[0] eq __PACKAGE__) { # Called as UNIVERSAL::import. Carp::croak("UNIVERSAL does not export anything"); } else { # Called as part of lookup from some other package. Carp::carp("Useless arguments provided to $_[0]::import: @_"); } } Combined with a warning in the core language to cover the case when UNIVERSAL hasn't been loaded.
Subject: Re: [perl #132425] Suggested warning on attempt to 'use' with arguments when no import() subroutine exists
Date: Thu, 16 Nov 2017 11:28:47 +0100
From: Sawyer X <xsawyerx [...] gmail.com>
To: perlbug-followup [...] perl.org
CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.5k
On 11/11/2017 06:43 PM, Hugo van der Sanden via RT wrote: Show quoted text
> On Sat, 11 Nov 2017 02:44:01 -0800, zefram@fysh.org wrote:
>> Hugo van der Sanden via RT wrote:
>>> But every module gets an import subroutine: if not their own, their >>> parent's (and at least UNIVERSAL's).
>> No, UNIVERSAL doesn't contain an import method. There's specific logic >> in the method calling mechanism that provides what amounts to an empty >> method if "import" or "unimport" is being looked up and there isn't any >> actual method, but ->can can see the lack of a method: >> >> $ perl -lwe 'print "main"->can("import") // "no method"; print eval { >> "main"->import; 1 } ? "ok" : "fail"' >> no method >> ok
> That looks hard to distinguish from 'has an import method, but can() lies about it'. :) > > But in any case the answer changes if anything has loaded UNIVERSAL: > % perl -MUNIVERSAL -lwe 'print "main"->can("import") // "no method"; print eval { "main"->import(1); 1 } ? "ok" : "fail"' > CODE(0x1561678) > ok > % > > For Ed's original suggestion: if we can reliably detect that there's no explicit import() in the inheritance chain, the suggestion of warning on a useless import arg seems valid, but the above suggests to me that the result would vary depending on whether UNIVERSAL had been loaded, which would at best make it less useful and at worst invalidate the idea.
I agree this is a good suggestion if we could reliably detect it. I'm not versed enough with the technical details on this but if we can determine we cannot reliably detect this, we should close the ticket.
From: Zefram <zefram [...] fysh.org>
To: perl5-porters [...] perl.org
Subject: Re: [perl #132425] Suggested warning on attempt to 'use' with arguments when no import() subroutine exists
Date: Thu, 16 Nov 2017 10:45:17 +0000
Sawyer X wrote: Show quoted text
>I agree this is a good suggestion if we could reliably detect it.
The import method from the UNIVERSAL module is itself a way of detecting a bad import call. It has explicit code to do nothing if called on a package other than UNIVERSAL, imitating the core behaviour when there's no import method. At the same time as introducing different core behaviour, we could extend this import method to imitate the new core behaviour. It's nasty to have a non-empty UNIVERSAL module. That import method exists only to support "use UNIVERSAL;", but that's a pretty silly usage since the only thing it installs is that import method. (It's also not a usage advised by the module's synopsis.) I think, independent of what we do with unhandled import calls, we should deprecate "use UNIVERSAL;" and ultimately delete that import method. People who just want to load the module to check its version number can "use UNIVERSAL ();". Or, more radically, we could remove the module entirely and turn it into just a .pod file, though we'd want to make sure the package name remained reserved in PAUSE. -zefram
CC: bugs-bitbucket [...] rt.perl.org
To: Perl 5 Porters <perl5-porters [...] perl.org>
From: David Nicol <davidnicol [...] gmail.com>
Date: Thu, 16 Nov 2017 10:05:33 -0600
Subject: Re: [perl #132425] Suggested warning on attempt to 'use' with arguments when no import() subroutine exists
Download (untitled) / with headers
text/plain 618b

untested draft. Extra points for revising to pull file, line data out of correct layer of caller() data.

cat > NoImportWarning.pm <<END
package WarnOnUseWithoutImport;

sub UNIVERSAL::import {
 @_ == 1 and return;
 warn "PACKAGE $_[0] USED WITH ARGUMENTS\n"
};
END

On Fri, Nov 10, 2017 at 6:33 AM, Ed Avis <perlbug-followup@perl.org> wrote: Show quoted text
% echo 'package A; sub foo {}; 1;' >A.pm
% perl -wE 'use A qw(foo)'

This should print something like

   You asked to import 'foo' from package A, but that package does not
   define an import() subroutine, so nothing has been imported.

--
Hi-jinks ensue.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org