Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 795006 - [Future EAPI] call eclass_init functions for all inherited eclasses, which resembles constructor usage in any other language
Summary: [Future EAPI] call eclass_init functions for all inherited eclasses, which re...
Status: CONFIRMED
Alias: None
Product: Gentoo Hosted Projects
Classification: Unclassified
Component: PMS/EAPI (show other bugs)
Hardware: All All
: Normal enhancement (vote)
Assignee: PMS/EAPI
URL: https://github.com/zmedico/filebus/bl...
Whiteboard:
Keywords:
Depends on:
Blocks: future-eapi
  Show dependency tree
 
Reported: 2021-06-08 23:03 UTC by Zac Medico
Modified: 2021-06-09 07:54 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zac Medico gentoo-dev 2021-06-08 23:03:00 UTC
If we add support for an eclass_init function which is always called when an eclass is inherited, then it provides an very organized way to group global scope code and variable assignments, in a way the resembles constructor usage in any other language.

For example, global scope code and variables from python-utils-r1.eclass can be migrated into an eclass init function like this:

> EXPORT_FUNCTIONS eclass_init
> 
> distutils-r1_eclass_init() {
> 	# NOTE: When dropping support for EAPIs here, we need to update
> 	# metadata/install-qa-check.d/60python-pyc
> 	# See bug #704286, bug #781878
> 	case "${EAPI:-0}" in
> 		[0-5]) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
> 		[6-7]) ;;
> 		*)     die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" ;;
> 	esac
> 
> 	if [[ ${_PYTHON_ECLASS_INHERITED} ]]; then
> 		die 'python-r1 suite eclasses can not be used with python.eclass.'
> 	fi
> 
> 	if [[ ! ${_PYTHON_UTILS_R1} ]]; then
> 
> 	inherit toolchain-funcs
> 
> 	# @ECLASS-VARIABLE: _PYTHON_ALL_IMPLS
> 	# @INTERNAL
> 	# @DESCRIPTION:
> 	# All supported Python implementations, most preferred last.
> 	_PYTHON_ALL_IMPLS=(
> 		pypy3
> 		python3_{8..10}
> 	)
> 	readonly _PYTHON_ALL_IMPLS
> 
> 	# @ECLASS-VARIABLE: _PYTHON_HISTORICAL_IMPLS
> 	# @INTERNAL
> 	# @DESCRIPTION:
> 	# All historical Python implementations that are no longer supported.
> 	_PYTHON_HISTORICAL_IMPLS=(
> 		jython2_7
> 		pypy pypy1_{8,9} pypy2_0
> 		python2_{5..7}
> 		python3_{1..7}
> 	)
> 	readonly _PYTHON_HISTORICAL_IMPLS
> }
Comment 1 Ulrich Müller gentoo-dev 2021-06-09 07:03:03 UTC
> EXPORT_FUNCTIONS eclass_init

So conceptually, eclass_init would be a new phase function? That seems to follow from its being used as a parameter of EXPORT_FUNCTIONS?

> 	if [[ ! ${_PYTHON_UTILS_R1} ]]; then
> 
> 	inherit toolchain-funcs

What would be the consequences of allowing inherit() to be called from within a phase function, or from within an if-conditional? Wouldn't that break metadata invariance, e.g., if the inherited eclass defines *DEPEND?
Comment 2 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2021-06-09 07:22:19 UTC
What would be the exact difference between calling it in global scope vs via this method?
Comment 3 Zac Medico gentoo-dev 2021-06-09 07:24:43 UTC
(In reply to Ulrich Müller from comment #1)
> > EXPORT_FUNCTIONS eclass_init
> 
> So conceptually, eclass_init would be a new phase function? That seems to
> follow from its being used as a parameter of EXPORT_FUNCTIONS?

Yeah, this is one possible way to implement it.

> > 	if [[ ! ${_PYTHON_UTILS_R1} ]]; then
> > 
> > 	inherit toolchain-funcs
> 
> What would be the consequences of allowing inherit() to be called from
> within a phase function, or from within an if-conditional? Wouldn't that
> break metadata invariance, e.g., if the inherited eclass defines *DEPEND?

The eclass_init function is special in the sense that it's invoked *during* inherit, so the effect is very similar to the global scope code that we have now. In effect, the main difference is only that the global scope code and variable assignments have migrated from global scope to a function that has been given a similar role.

(In reply to Michał Górny from comment #2)
> What would be the exact difference between calling it in global scope vs via
> this method?

The intention is for the exact difference to be nil. However, I think the visual benefit is obvious, since it resembles constructor usage in any other language.
Comment 4 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2021-06-09 07:48:42 UTC
I don't see any gain from it, compared to just calling the just-declared function in global scope.  You will have to do it anyway for older EAPI support.

Besides you should note that doing global stuff in function is tricky.  Particularly, 'declare' defaults to creating local variables.
Comment 5 Zac Medico gentoo-dev 2021-06-09 07:54:02 UTC
(In reply to Michał Górny from comment #4)
> I don't see any gain from it, compared to just calling the just-declared
> function in global scope.  You will have to do it anyway for older EAPI
> support.

It establishes a unified practice that we can apply to any eclass with EXPORT_FUNCTIONS eclass_init. It's valuable to have a practice that can be applied consistently.

> Besides you should note that doing global stuff in function is tricky. 
> Particularly, 'declare' defaults to creating local variables.

That's a valid point, but since valid syntax exists, I do see it as a show stopper. It's always possible to write incorrect code.