1 |
round two of the patch, still is missing... |
2 |
|
3 |
|
4 |
On Sun, Feb 18, 2007 at 06:27:59PM +0000, Marius Mauch wrote: |
5 |
> Author: genone |
6 |
> Date: 2007-02-18 18:27:59 +0000 (Sun, 18 Feb 2007) |
7 |
> New Revision: 5993 |
8 |
> |
9 |
> Modified: |
10 |
> main/trunk/pym/portage/dbapi/vartree.py |
11 |
> Log: |
12 |
> extend check for internal references, should remove all libs that are only used internally now |
13 |
> |
14 |
> Modified: main/trunk/pym/portage/dbapi/vartree.py |
15 |
> =================================================================== |
16 |
> --- main/trunk/pym/portage/dbapi/vartree.py 2007-02-18 15:38:56 UTC (rev 5992) |
17 |
> +++ main/trunk/pym/portage/dbapi/vartree.py 2007-02-18 18:27:59 UTC (rev 5993) |
18 |
> @@ -1266,14 +1266,33 @@ |
19 |
> preserve_libs = old_libs.difference(mylibs) |
20 |
> |
21 |
> # ignore any libs that are only internally used by the package |
22 |
> - for lib in preserve_libs.copy(): |
23 |
> - old_contents_without_libs = [x for x in old_contents if os.path.basename(x) not in preserve_libs] |
24 |
> - if len(set(libmap[lib]).intersection(old_contents_without_libs)) == len(libmap[lib]): |
25 |
> - preserve_libs.remove(lib) |
26 |
> + def has_external_consumers(lib, contents, otherlibs): |
27 |
> + consumers = set(libmap[lib]) |
28 |
|
29 |
# this should be done *once*. |
30 |
# further, if libmap where k->set, you'd avoid repeated |
31 |
# creation of sets all over the damn place. |
32 |
|
33 |
> + contents_without_libs = [x for x in contents if not os.path.basename(x) in otherlibs] |
34 |
|
35 |
# os.path.basename invocations aren't horribly expensive, but the |
36 |
> + |
37 |
> + # just used by objects that will be autocleaned |
38 |
> + if len(consumers.difference(contents_without_libs)) == 0: |
39 |
|
40 |
if not consumers.difference(contents_without_libs)):... |
41 |
# no point in doing the len, thus don't. |
42 |
# standard behaviour in python code to rely on bool protocol, thus do |
43 |
# so. |
44 |
|
45 |
> + return False |
46 |
> + # used by objects that are referenced as well, need to check those |
47 |
> + # recursively to break any reference cycles |
48 |
> + elif len(consumers.difference(contents)) == 0: |
49 |
|
50 |
# same. len isn't needed, thus don't use it. |
51 |
# majority of builtins *do* support boolean, thus use it. |
52 |
|
53 |
> + otherlibs = set(otherlibs) |
54 |
|
55 |
# this will explode. you're passing None in below. |
56 |
|
57 |
> + for ol in otherlibs.intersection(consumers): |
58 |
> + if has_external_consumers(ol, contents, otherlibs.copy().remove(lib)): |
59 |
|
60 |
no way that code is right. |
61 |
1) you're copying a set, then removing an item from it. |
62 |
2) remove is a Py_RETURN_NONE, meaning it returns None. you're |
63 |
literally cloning a set, poping an item from it, and then |
64 |
throwing away the set, passing None into has_external_consumers |
65 |
3) algo in general could be replaced by just doing walks over the |
66 |
target preserve libs, pruning until a walk doesn't prune anything. |
67 |
Runtime ought to be better, less daft copys, saner to read also. |
68 |
|
69 |
> + return True |
70 |
> + return False |
71 |
> + # used by external objects directly |
72 |
> + else: |
73 |
> + return True |
74 |
> + |
75 |
> + for lib in list(preserve_libs): |
76 |
> + if not has_external_consumers(lib, old_contents, preserve_libs): |
77 |
> + preserve_libs.remove(lib) |
78 |
|
79 |
# this is a bit retarded... for handling libs referring to each other, |
80 |
# code above continually recalculates. |
81 |
# reverse the mapping, and work from that angle; should avoid having |
82 |
# to do this insane little dance. |
83 |
|
84 |
> |
85 |
> # get the real paths for the libs |
86 |
> preserve_paths = [x for x in old_contents if os.path.basename(x) in preserve_libs] |
87 |
> - |
88 |
> + del old_contents, old_libs, mylibs, preserve_libs |
89 |
> + |
90 |
> # inject files that should be preserved into our image dir |
91 |
> import shutil |
92 |
> for x in preserve_paths: |
93 |
> @@ -1293,7 +1312,7 @@ |
94 |
> preserve_paths.append(linktarget) |
95 |
> else: |
96 |
> shutil.copy2(x, os.path.join(srcroot, x.lstrip(os.sep))) |
97 |
> - |
98 |
> + del preserve_paths |
99 |
> |
100 |
> # check for package collisions |
101 |
> if "collision-protect" in self.settings.features: |
102 |
> |
103 |
|
104 |
Aside from my earlier suggestion that you should pop this crap out of |
105 |
svn and work it out outside of mainline, breaking it out into a func |
106 |
and doing tests for the func might be wise- very least easier for you |
107 |
to iron it out so it behaves. Upshot, makes it easier for someone to |
108 |
refactor it down the line. |
109 |
|
110 |
Still have the crappy forced double walk of ${D} regression also. |
111 |
|
112 |
~harring |