@@ -187,6 +187,37 @@ def _from_text_for(cls, text, dist):
187
187
return cls (ep ._for (dist ) for ep in EntryPoint ._from_text (text ))
188
188
189
189
190
+ class SelectableGroups (dict ):
191
+ """
192
+ A backward- and forward-compatible result from
193
+ entry_points that fully implements the dict interface.
194
+ """
195
+
196
+ @classmethod
197
+ def load (cls , eps ):
198
+ by_group = operator .attrgetter ('group' )
199
+ ordered = sorted (eps , key = by_group )
200
+ grouped = itertools .groupby (ordered , by_group )
201
+ return cls ((group , EntryPoints (eps )) for group , eps in grouped )
202
+
203
+ @property
204
+ def groups (self ):
205
+ return self .keys ()
206
+
207
+ @property
208
+ def names (self ):
209
+ return (ep .name for ep in self ._all )
210
+
211
+ @property
212
+ def _all (self ):
213
+ return itertools .chain .from_iterable (self .values ())
214
+
215
+ def select (self , ** params ):
216
+ if not params :
217
+ return self
218
+ return EntryPoints (self ._all ).select (** params )
219
+
220
+
190
221
class LegacyGroupedEntryPoints (EntryPoints ):
191
222
"""
192
223
Compatibility wrapper around EntryPoints to provide
@@ -713,16 +744,25 @@ def version(distribution_name):
713
744
return distribution (distribution_name ).version
714
745
715
746
716
- def entry_points (** params ):
747
+ def entry_points (** params ) -> Union [ EntryPoints , SelectableGroups ] :
717
748
"""Return EntryPoint objects for all installed packages.
718
749
719
- :return: EntryPoint objects for all installed packages.
750
+ For compatibility, returns ``SelectableGroups`` object unless
751
+ selection parameters are supplied. In the future, this function
752
+ will return ``LegacyGroupedEntryPoints`` instead of
753
+ ``SelectableGroups`` and eventually will only return
754
+ ``EntryPoints``.
755
+
756
+ For maximum future compatibility, pass selection parameters
757
+ or invoke ``.select`` with parameters on the result.
758
+
759
+ :return: EntryPoints or SelectableGroups for all installed packages.
720
760
"""
721
761
unique = functools .partial (unique_everseen , key = operator .attrgetter ('name' ))
7
6293
22
762
eps = itertools .chain .from_iterable (
723
763
dist .entry_points for dist in unique (distributions ())
724
764
)
725
- return LegacyGroupedEntryPoints (eps ).select (** params )
765
+ return SelectableGroups . load (eps ).select (** params )
726
766
727
767
728
768
def files (distribution_name ):
0 commit comments