1414from ._abc import Loader
1515import abc
1616import warnings
17+ from typing import BinaryIO , Iterable , Text
1718from typing import Protocol , runtime_checkable
1819
1920
@@ -297,49 +298,45 @@ def set_data(self, path, data):
297298
298299
299300class ResourceReader (metaclass = abc .ABCMeta ):
300-
301- """Abstract base class to provide resource-reading support.
302-
303- Loaders that support resource reading are expected to implement
304- the ``get_resource_reader(fullname)`` method and have it either return None
305- or an object compatible with this ABC.
306- """
301+ """Abstract base class for loaders to provide resource reading support."""
307302
308303 @abc .abstractmethod
309- def open_resource (self , resource ) :
304+ def open_resource (self , resource : Text ) -> BinaryIO :
310305 """Return an opened, file-like object for binary reading.
311306
312- The 'resource' argument is expected to represent only a file name
313- and thus not contain any subdirectory components.
314-
307+ The 'resource' argument is expected to represent only a file name.
315308 If the resource cannot be found, FileNotFoundError is raised.
316309 """
310+ # This deliberately raises FileNotFoundError instead of
311+ # NotImplementedError so that if this method is accidentally called,
312+ # it'll still do the right thing.
317313 raise FileNotFoundError
318314
319315 @abc .abstractmethod
320- def resource_path (self , resource ) :
316+ def resource_path (self , resource : Text ) -> Text :
321317 """Return the file system path to the specified resource.
322318
323- The 'resource' argument is expected to represent only a file name
324- and thus not contain any subdirectory components.
325-
319+ The 'resource' argument is expected to represent only a file name.
326320 If the resource does not exist on the file system, raise
327321 FileNotFoundError.
328322 """
323+ # This deliberately raises FileNotFoundError instead of
324+ # NotImplementedError so that if this method is accidentally called,
325+ # it'll still do the right thing.
329326 raise FileNotFoundError
330327
331328 @abc .abstractmethod
332- def is_resource (self , name ):
333- """Return True if the named 'name' is consider a resource."""
329+ def is_resource (self , path : Text ) -> bool :
330+ """Return True if the named 'path' is a resource.
331+
332+ Files are resources, directories are not.
333+ """
334334 raise FileNotFoundError
335335
336336 @abc .abstractmethod
337- def contents (self ):
338- """Return an iterable of strings over the contents of the package."""
339- return []
340-
341-
342- _register (ResourceReader , machinery .SourceFileLoader )
337+ def contents (self ) -> Iterable [str ]:
338+ """Return an iterable of entries in `package`."""
339+ raise FileNotFoundError
343340
344341
345342@runtime_checkable
@@ -355,26 +352,28 @@ def iterdir(self):
355352 Yield Traversable objects in self
356353 """
357354
358- @abc .abstractmethod
359355 def read_bytes (self ):
360356 """
361357 Read contents of self as bytes
362358 """
359+ with self .open ('rb' ) as strm :
360+ return strm .read ()
363361
364- @abc .abstractmethod
365362 def read_text (self , encoding = None ):
366363 """
367- Read contents of self as bytes
364+ Read contents of self as text
368365 """
366+ with self .open (encoding = encoding ) as strm :
367+ return strm .read ()
369368
370369 @abc .abstractmethod
371- def is_dir (self ):
370+ def is_dir (self ) -> bool :
372371 """
373372 Return True if self is a dir
374373 """
375374
376375 @abc .abstractmethod
377- def is_file (self ):
376+ def is_file (self ) -> bool :
378377 """
379378 Return True if self is a file
380379 """
@@ -385,11 +384,11 @@ def joinpath(self, child):
385384 Return Traversable child in self
386385 """
387386
388- @abc .abstractmethod
389387 def __truediv__ (self , child ):
390388 """
391389 Return Traversable child in self
392390 """
391+ return self .joinpath (child )
393392
394393 @abc .abstractmethod
395394 def open (self , mode = 'r' , * args , ** kwargs ):
@@ -402,14 +401,18 @@ def open(self, mode='r', *args, **kwargs):
402401 """
403402
404403 @abc .abstractproperty
405- def name (self ):
406- # type: () -> str
404+ def name (self ) -> str :
407405 """
408406 The base name of this object without any parent references.
409407 """
410408
411409
412410class TraversableResources (ResourceReader ):
411+ """
412+ The required interface for providing traversable
413+ resources.
414+ """
415+
413416 @abc .abstractmethod
414417 def files (self ):
415418 """Return a Traversable object for the loaded package."""
0 commit comments