11from __future__ import annotations
22
3+ import enum
4+
5+ from collections import OrderedDict
6+ from enum import IntEnum
37from typing import TYPE_CHECKING
48
59from poetry .repositories .exceptions import PackageNotFound
1317 from poetry .repositories .repository import Repository
1418
1519
20+ class Priority (IntEnum ):
21+ # The order of the members below dictates the actual priority. The first member has
22+ # top priority.
23+ DEFAULT = enum .auto ()
24+ PRIMARY = enum .auto ()
25+ SECONDARY = enum .auto ()
26+
27+
1628class Pool :
1729 def __init__ (
1830 self ,
1931 repositories : list [Repository ] | None = None ,
2032 ignore_repository_names : bool = False ,
2133 ) -> None :
2234 self ._name = "poetry-pool"
35+ self ._repositories : OrderedDict [
36+ str , tuple [Repository , RepositoryPriority ]
37+ ] = OrderedDict ()
38+ self ._ignore_repository_names = ignore_repository_names
2339
2440 if repositories is None :
2541 repositories = []
26-
27- self ._lookup : dict [str , int ] = {}
28- self ._repositories : list [Repository ] = []
29- self ._default = False
30- self ._has_primary_repositories = False
31- self ._secondary_start_idx : int | None = None
32-
3342 for repository in repositories :
3443 self .add_repository (repository )
3544
36- self ._ignore_repository_names = ignore_repository_names
37-
3845 @property
3946 def name (self ) -> str :
4047 return self ._name
4148
4249 @property
4350 def repositories (self ) -> list [Repository ]:
44- return self ._repositories
51+ unsorted_repositories = self ._repositories .values ()
52+ sorted_repositories = sorted (unsorted_repositories , key = lambda p : p [1 ].value )
53+ return [repo for (repo , _ ) in sorted_repositories ]
4554
4655 def has_default (self ) -> bool :
47- return self ._default
56+ return self ._contains_priority ( Priority . DEFAULT )
4857
4958 def has_primary_repositories (self ) -> bool :
50- return self ._has_primary_repositories
59+ return self ._contains_priority (Priority .PRIMARY )
60+
61+ def _contains_priority (self , priority : Priority ) -> bool :
62+ return any (
63+ repo_prio is priority for _ , repo_prio in self ._repositories .values ()
64+ )
5165
5266 def has_repository (self , name : str ) -> bool :
53- return name .lower () in self ._lookup
67+ return name .lower () in self ._repositories
5468
5569 def repository (self , name : str ) -> Repository :
5670 name = name .lower ()
57-
58- lookup = self ._lookup .get (name )
59- if lookup is not None :
60- return self ._repositories [lookup ]
61-
62- raise ValueError (f'Repository "{ name } " does not exist.' )
71+ if self .has_repository (name ):
72+ return self ._repositories [name ][0 ]
73+ raise IndexError (f'Repository "{ name } " does not exist.' )
6374
6475 def add_repository (
6576 self , repository : Repository , default : bool = False , secondary : bool = False
@@ -68,130 +79,59 @@ def add_repository(
6879 Adds a repository to the pool.
6980 """
7081 repository_name = repository .name .lower ()
71- if repository_name in self ._lookup :
72- raise ValueError (f"{ repository_name } already added" )
73-
74- if default :
75- if self .has_default ():
76- raise ValueError ("Only one repository can be the default" )
77-
78- self ._default = True
79- self ._repositories .insert (0 , repository )
80- for name in self ._lookup :
81- self ._lookup [name ] += 1
82+ if self .has_repository (repository_name ):
83+ raise ValueError (
84+ f"A repository with name { repository_name } was already added."
85+ )
8286
83- if self ._secondary_start_idx is not None :
84- self . _secondary_start_idx += 1
87+ if default and self .has_default () :
88+ raise ValueError ( "Only one repository can be the default." )
8589
86- self ._lookup [repository_name ] = 0
90+ priority = Priority .PRIMARY
91+ if default :
92+ priority = Priority .DEFAULT
8793 elif secondary :
88- if self ._secondary_start_idx is None :
89- self ._secondary_start_idx = len (self ._repositories )
90-
91- self ._repositories .append (repository )
92- self ._lookup [repository_name ] = len (self ._repositories ) - 1
93- else :
94- self ._has_primary_repositories = True
95- if self ._secondary_start_idx is None :
96- self ._repositories .append (repository )
97- self ._lookup [repository_name ] = len (self ._repositories ) - 1
98- else :
99- self ._repositories .insert (self ._secondary_start_idx , repository )
100-
101- for name , idx in self ._lookup .items ():
102- if idx < self ._secondary_start_idx :
103- continue
104-
105- self ._lookup [name ] += 1
106-
107- self ._lookup [repository_name ] = self ._secondary_start_idx
108- self ._secondary_start_idx += 1
109-
94+ priority = Priority .SECONDARY
95+ self ._repositories [repository_name ] = (repository , priority )
11096 return self
11197
112- def remove_repository (self , repository_name : str ) -> Pool :
113- if repository_name is not None :
114- repository_name = repository_name .lower ()
115-
116- idx = self ._lookup .get (repository_name )
117- if idx is not None :
118- del self ._repositories [idx ]
119- del self ._lookup [repository_name ]
120-
121- if idx == 0 :
122- self ._default = False
123-
124- for name in self ._lookup :
125- if self ._lookup [name ] > idx :
126- self ._lookup [name ] -= 1
127-
128- if (
129- self ._secondary_start_idx is not None
130- and self ._secondary_start_idx > idx
131- ):
132- self ._secondary_start_idx -= 1
133-
98+ def remove_repository (self , name : str ) -> Pool :
99+ if not self .has_repository (name ):
100+ raise IndexError (f"Pool can not remove unknown repository '{ name } '." )
101+ del self ._repositories [name .lower ()]
134102 return self
135103
136104 def package (
137105 self ,
138106 name : str ,
139107 version : Version ,
140108 extras : list [str ] | None = None ,
141- repository : str | None = None ,
109+ repository_name : str | None = None ,
142110 ) -> Package :
143- if repository is not None :
144- repository = repository .lower ()
145-
146- if (
147- repository is not None
148- and repository not in self ._lookup
149- and not self ._ignore_repository_names
150- ):
151- raise ValueError (f'Repository "{ repository } " does not exist.' )
152-
153- if repository is not None and not self ._ignore_repository_names :
154- return self .repository (repository ).package (name , version , extras = extras )
111+ if repository_name and not self ._ignore_repository_names :
112+ return self .repository (repository_name ).package (
113+ name , version , extras = extras
114+ )
155115
156- for repo in self ._repositories :
116+ for repo in self .repositories :
157117 try :
158- package = repo .package (name , version , extras = extras )
118+ return repo .package (name , version , extras = extras )
159119 except PackageNotFound :
160120 continue
161-
162- return package
163-
164121 raise PackageNotFound (f"Package { name } ({ version } ) not found." )
165122
166123 def find_packages (self , dependency : Dependency ) -> list [Package ]:
167- repository = dependency .source_name
168- if repository is not None :
169- repository = repository .lower ()
170-
171- if (
172- repository is not None
173- and repository not in self ._lookup
174- and not self ._ignore_repository_names
175- ):
176- raise ValueError (f'Repository "{ repository } " does not exist.' )
177-
178- if repository is not None and not self ._ignore_repository_names :
179- return self .repository (repository ).find_packages (dependency )
180-
181- packages = []
182- for repo in self ._repositories :
183- packages += repo .find_packages (dependency )
124+ repository_name = dependency .source_name
125+ if repository_name and not self ._ignore_repository_names :
126+ return self .repository (repository_name ).find_packages (dependency )
184127
128+ packages : list [Package ] = []
129+ for repo in self .repositories :
130+ packages += repo .find_packages (dependency )
185131 return packages
186132
187133 def search (self , query : str ) -> list [Package ]:
188- from poetry .repositories .legacy_repository import LegacyRepository
189-
190- results = []
191- for repository in self ._repositories :
192- if isinstance (repository , LegacyRepository ):
193- continue
194-
134+ results : list [Package ] = []
135+ for repository in self .repositories :
195136 results += repository .search (query )
196-
197137 return results
0 commit comments