python PortGroup and destroot.pre_args

Ryan Schmidt ryandesign at macports.org
Fri Jul 2 09:31:50 UTC 2021


On Jun 29, 2021, at 15:35, René J.V. Bertin wrote:

> Hi,
> 
> There's a strange side effect of the Python PG on `destroot.pre_args` (and maybe other, related variables). Accessing the variable after including the PG leads to
> 
> {{{
> DEBUG: Sourced PortGroup python 1.0 from /path/to//_resources/port1.0/group/python-1.0.tcl
> DEBUG: can't read "name": no such variable
>    while executing
> "set $option"
>    (procedure "option" line 10)
>    invoked from within
> "option name"
>    (procedure "python_get_version" line 2)
>    invoked from within
> "python_get_version"
>    invoked from within
> "subst {[python_get_version]}"
>    invoked from within
> "set python.version [subst {[python_get_version]}]"
>    ("uplevel" body line 1)
>    invoked from within
> "uplevel #0 [list set $optionName] [subst -nocommands {[subst {$option_defaults($optionName)}]}]"
>    (procedure "default_check" line 10)
>    invoked from within
> "default_check python.version {} read"
>    (read trace on "python.version")
>    invoked from within
> "string range ${python.version} 0 end-1"
>    invoked from within
> "subst {[string range ${python.version} 0 end-1].[string index ${python.version} end]}"
>    invoked from within
> "set python.branch [subst {[string range ${python.version} 0 end-1].[string index ${python.version} end]}]"
>    ("uplevel" body line 1)
>    invoked from within
> "uplevel #0 [list set $optionName] [subst -nocommands {[subst {$option_defaults($optionName)}]}]"
>    (procedure "default_check" line 10)
>    invoked from within
> "default_check python.branch {} read"
>    (read trace on "python.branch")
>    invoked from within
> "subst {${frameworks_dir}/Python.framework/Versions/${python.branch}}"
>    invoked from within
> "set python.prefix [subst {${frameworks_dir}/Python.framework/Versions/${python.branch}}]"
>    ("uplevel" body line 1)
>    invoked from within
> "uplevel #0 [list set $optionName] [subst -nocommands {[subst {$option_defaults($optionName)}]}]"
>    (procedure "default_check" line 10)
>    invoked from within
> "default_check python.prefix {} read"
>    (read trace on "python.prefix")
>    invoked from within
> "subst {${python.prefix}/bin/python${python.branch}}"
>    invoked from within
> "set python.bin [subst {${python.prefix}/bin/python${python.branch}}]"
>    ("uplevel" body line 1)
>    invoked from within
> "uplevel #0 [list set $optionName] [subst -nocommands {[subst {$option_defaults($optionName)}]}]"
>    (procedure "default_check" line 10)
>    invoked from within
> "default_check python.bin {} read"
>    (read trace on "python.bin")
>    invoked from within
> "subst {${python.bin} setup.py --no-user-cfg}"
>    invoked from within
> "set destroot.cmd [subst {${python.bin} setup.py --no-user-cfg}]"
>    ("uplevel" body line 1)
>    invoked from within
> "uplevel #0 [list set $optionName] [subst -nocommands {[subst {$option_defaults($optionName)}]}]"
>    (procedure "default_check" line 10)
>    invoked from within
> "default_check destroot.cmd {} read"
>    (read trace on "destroot.cmd")
>    invoked from within
> "set $option"
>    (procedure "option" line 10)
>    invoked from within
> "option destroot.cmd"
>    (procedure "portdestroot::destroot_getargs" line 2)
>    invoked from within
> "portdestroot::destroot_getargs"
>    invoked from within
> "subst {[portdestroot::destroot_getargs]}"
>    invoked from within
> "set destroot.pre_args [subst {[portdestroot::destroot_getargs]}]"
>    ("uplevel" body line 1)
>    invoked from within
> "uplevel #0 [list set $optionName] [subst -nocommands {[subst {$option_defaults($optionName)}]}]"
>    (procedure "default_check" line 10)
>    invoked from within
> "default_check destroot.pre_args {} read"
>    (read trace on "destroot.pre_args")
>    invoked from within
> "ui_msg ${destroot.pre_args}"
>    (file "Portfile" line 5)
>    invoked from within
> "source Portfile"
>    invoked from within
> "$workername eval {source Portfile}"
>    (procedure "mportopen" line 50)
>    invoked from within
> "mportopen $url"
> }}}
> 
> Why would `name` have to be defined in order to be able to evaluate destroot.pre_args ?


If I create a dummy portfile that includes the python portgroup then then immediately tries to print destroot.pre_args, it shows why it failed:


Can't map the URL 'file://.' to a port description file ("can't read "destroot.pre_args": can't read "destroot.cmd": can't read "python.bin": can't read "python.prefix": can't read "python.branch": can't read "python.version": can't read "name": no such variable").


If you read that in reverse, you see that it needs name to compute python.version (i.e. if name were py27-foo, then python.version would be 27), which is needed to compute python.branch, which is needed to construct python.prefix, which is needed for python.bin, which is part of destroot.cmd (all of that is in the python portgroup), and destroot.cmd is needed to determine what to set destroot.pre_args to (that's in base).


The real question is why do you need to access destroot.pre_args right after including the python portgroup and before setting name? My advice is: don't do that. Follow our typical portfile arrangement, which generally involves including portgroups up top, then setting name and version (or calling a .setup procedure that does it for you), and if you need to inspect or modify destroot.pre_args, do it later in the portfile, for example near where all the other lines that relate to the destroot phase are.



More information about the macports-dev mailing list