1 |
Hello, |
2 |
|
3 |
I am still thinking what would be the best way of handling packages |
4 |
which support being built for a single Python implementation only |
5 |
(like packages embedding Python and not being boost). |
6 |
|
7 |
A few shortcuts for the scope of this mail: |
8 |
SIP - package supporting being built for a single implementation only |
9 |
MIP - package supporting being built for multiple implementations |
10 |
|
11 |
Now, the problem with SIP is that they can support only one Python |
12 |
implementation at a time. I'd like to find a solution which: |
13 |
|
14 |
1) would be the most user- and developer-friendly, |
15 |
|
16 |
2) would be transparent and explicit (user has to know which |
17 |
implementation is actually used, and be able to switch it), |
18 |
|
19 |
3) would not require different dependency atoms for dependencies which |
20 |
are SIP (i.e. the package just depends on another Python package, |
21 |
not caring whether it is SIP or MIP). |
22 |
|
23 |
|
24 |
So far, the solution of using REQUIRED_USE='^^ ( python_targets... )' |
25 |
fulfilled 2) & 3). Sadly, it is hardly user-friendly because whenever |
26 |
user has more than one Python implementation in PYTHON_TARGETS, he |
27 |
needs to explicitly disable other flags for each package. |
28 |
|
29 |
Additionally, this means that if SIP becomes a MIP, user is unaware |
30 |
of that and still explicitly disables additional implementations. |
31 |
|
32 |
I could live with that if not the fact that the default PYTHON_TARGETS |
33 |
currently list two implementations. Therefore, not only a specific |
34 |
group but all our users would be forced to switch flags like that. |
35 |
|
36 |
|
37 |
Hopefully, there's one way we could achieve a bit of user-friendliness |
38 |
for most of the cases. If we introduced an auxiliary variable, let's |
39 |
call it PYTHON_SINGLE_TARGET for now, it could work. |
40 |
|
41 |
The eclass used for SIP: |
42 |
|
43 |
1) adds PYTHON_SINGLE_TARGET flags (following PYTHON_COMPAT) to IUSE, |
44 |
|
45 |
2) adds REQUIRED_USE='^^ ( python_single_target... )', |
46 |
|
47 |
3) adds REQUIRED_USE='python_single_target...? ( python_targets... )', |
48 |
|
49 |
4) replaces PYTHON_USEDEP with: |
50 |
'python_targets...?,python_single_target...?(+)', |
51 |
|
52 |
5) sets the variables based on PYTHON_SINGLE_TARGET in pkg_setup(). |
53 |
|
54 |
Therefore, users can explicitly use PYTHON_SINGLE_TARGET to choose |
55 |
the target which would be user for SIP while keeping the complete |
56 |
PYTHON_TARGETS for MIP. It's much more friendly. |
57 |
|
58 |
|
59 |
Thanks to EAPI4 USE defaults, the ${PYTHON_USEDEP} works fine both |
60 |
for MIP and SIP deps. |
61 |
|
62 |
For a MIP dep, the PYTHON_TARGETS are used as the real check. |
63 |
PYTHON_SINGLE_TARGET aren't there and they default to enabled, |
64 |
so the check passes. The REQUIRED_USE ensures that PYTHON_TARGETS |
65 |
contains PYTHON_SINGLE_TARGET. |
66 |
|
67 |
For a SIP dep, the PYTHON_SINGLE_TARGET is available and becomes |
68 |
relevant. |
69 |
|
70 |
In the corner case when PYTHON_SINGLE_TARGET for package A specifies |
71 |
an implementation which is not supported by package B, |
72 |
the PYTHON_SINGLE_TARGET check succeeds (missing flag = enabled) |
73 |
but the PYTHON_TARGETS check fails due to missing flag. |
74 |
|
75 |
Of course, a MIP would not be allowed to depend on a SIP. |
76 |
|
77 |
|
78 |
The profiles would specify a single default implementation |
79 |
from PYTHON_TARGETS as a default for PYTHON_SINGLE_TARGET. This will |
80 |
effectively hide the issue from most of our users. |
81 |
|
82 |
Those who set PYTHON_TARGETS explicitly may need to adjust |
83 |
the PYTHON_SINGLE_TARGET. Considering that it will be common to all |
84 |
SIPs, it's much more friendly than switching per-package. |
85 |
|
86 |
|
87 |
The only real issue unsolved is friendly solving of Py2/3 issues with |
88 |
SIPs. If user has PYTHON_SINGLE_TARGET=python2_7, SIP package supporting |
89 |
Python3 only (is there any?) would require explicit flag setting. |
90 |
|
91 |
I believe that's a corner case. It could be solved if we invented some |
92 |
kind of 'automatic USE defaults'. In that case, profiles wouldn't |
93 |
specify a default but instead portage would pick one based on |
94 |
REQUIRED_USE constraints and flag order. |
95 |
|
96 |
In other words: |
97 |
- user has PYTHON_TARGETS='python2_7 python3_2', |
98 |
- package has PYTHON_COMPAT=( python{2_6,2_7} ), |
99 |
-> per-package PYTHON_TARGETS becomes 'python2_7', |
100 |
- REQUIRED_USE='^^ ( pst2_6 pst2_7 ) pst2_6? ( py2_6 ) ...' |
101 |
-> portage tries pst2_6... |
102 |
--> py2_6 not set, REQUIRED_USE unsatisfied; |
103 |
-> portage tries pst2_7 |
104 |
--> py2_7 set, all ok. |
105 |
---> PYTHON_SINGLE_TARGET=python2_7 |
106 |
|
107 |
But that's not really necessary right now, I think. |
108 |
|
109 |
|
110 |
To sum it up quickly, the aux variable solution: |
111 |
|
112 |
Advantages: |
113 |
- painless for most of our users, |
114 |
- explicit, transparent, |
115 |
- simple and matching SIP->SIP and SIP->MIP deps. |
116 |
|
117 |
Disadvantages: |
118 |
- a bit redundant, |
119 |
- does not solve the issue for py3-only SIP packages, |
120 |
- may require explicit action when changing PYTHON_TARGETS. |
121 |
|
122 |
What are your thoughts? |
123 |
|
124 |
-- |
125 |
Best regards, |
126 |
Michał Górny |