Skip to content

Commit

Permalink
pythongh-125633: Add function ispackage to stdlib inspect (python…
Browse files Browse the repository at this point in the history
…#125634)

---------

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
  • Loading branch information
Xiaokang2022 and blurb-it[bot] authored Oct 27, 2024
1 parent c51b560 commit dad3453
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 6 deletions.
7 changes: 7 additions & 0 deletions Doc/library/inspect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,13 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
Return ``True`` if the object is a bound method written in Python.


.. function:: ispackage(object)

Return ``True`` if the object is a :term:`package`.

.. versionadded:: 3.14


.. function:: isfunction(object)

Return ``True`` if the object is a Python function, which includes functions
Expand Down
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ inspect
If true, string :term:`annotations <annotation>` are displayed without surrounding quotes.
(Contributed by Jelle Zijlstra in :gh:`101552`.)

* Add function :func:`inspect.ispackage` to determine whether an object is a
:term:`package` or not.
(Contributed by Zhikang Yan in :gh:`125634`.)


json
----
Expand Down
11 changes: 8 additions & 3 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
Here are some of the useful functions provided by this module:
ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),
isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),
isroutine() - check object types
ismodule(), isclass(), ismethod(), ispackage(), isfunction(),
isgeneratorfunction(), isgenerator(), istraceback(), isframe(),
iscode(), isbuiltin(), isroutine() - check object types
getmembers() - get members of an object that satisfy a given condition
getfile(), getsourcefile(), getsource() - find an object's source code
Expand Down Expand Up @@ -128,6 +128,7 @@
"ismethoddescriptor",
"ismethodwrapper",
"ismodule",
"ispackage",
"isroutine",
"istraceback",
"markcoroutinefunction",
Expand Down Expand Up @@ -186,6 +187,10 @@ def ismethod(object):
"""Return true if the object is an instance method."""
return isinstance(object, types.MethodType)

def ispackage(object):
"""Return true if the object is a package."""
return ismodule(object) and hasattr(object, "__path__")

def ismethoddescriptor(object):
"""Return true if the object is a method descriptor.
Expand Down
19 changes: 16 additions & 3 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

# Functions tested in this suite:
# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
# isbuiltin, isroutine, isgenerator, ispackage, isgeneratorfunction, getmembers,
# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
# getclasstree, getargvalues, formatargvalues, currentframe,
# stack, trace, ismethoddescriptor, isdatadescriptor, ismethodwrapper
Expand Down Expand Up @@ -105,7 +105,7 @@ def unsorted_keyword_only_parameters_fn(*, throw, out, the, baby, with_,
class IsTestBase(unittest.TestCase):
predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
inspect.isframe, inspect.isfunction, inspect.ismethod,
inspect.ismodule, inspect.istraceback,
inspect.ismodule, inspect.istraceback, inspect.ispackage,
inspect.isgenerator, inspect.isgeneratorfunction,
inspect.iscoroutine, inspect.iscoroutinefunction,
inspect.isasyncgen, inspect.isasyncgenfunction,
Expand All @@ -121,7 +121,10 @@ def istest(self, predicate, exp):
predicate == inspect.iscoroutinefunction) and \
other == inspect.isfunction:
continue
self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
if predicate == inspect.ispackage and other == inspect.ismodule:
self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
else:
self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))

def test__all__(self):
support.check__all__(self, inspect, not_exported=("modulesbyfile",), extra=("get_annotations",))
Expand Down Expand Up @@ -201,7 +204,17 @@ def test_excluding_predicates(self):
self.assertFalse(inspect.ismethodwrapper(int))
self.assertFalse(inspect.ismethodwrapper(type("AnyClass", (), {})))

def test_ispackage(self):
self.istest(inspect.ispackage, 'asyncio')
self.istest(inspect.ispackage, 'importlib')
self.assertFalse(inspect.ispackage(inspect))
self.assertFalse(inspect.ispackage(mod))
self.assertFalse(inspect.ispackage(':)'))

class FakePackage:
__path__ = None

self.assertFalse(inspect.ispackage(FakePackage()))

def test_iscoroutine(self):
async_gen_coro = async_generator_function_example(1)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add function :func:`inspect.ispackage` to determine whether an object is a
:term:`package` or not.

0 comments on commit dad3453

Please sign in to comment.