https://github.com/python/cpython/commit/dad34531298fc0ea91b9000aafdd2ea2fce5e54a
commit: dad34531298fc0ea91b9000aafdd2ea2fce5e54a
branch: main
author: Zhikang Yan <[email protected]>
committer: ncoghlan <[email protected]>
date: 2024-10-27T14:57:43+10:00
summary:
gh-125633: Add function `ispackage` to stdlib `inspect` (#125634)
---------
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2024-10-17-04-52-00.gh-issue-125633.lMck06.rst
M Doc/library/inspect.rst
M Doc/whatsnew/3.14.rst
M Lib/inspect.py
M Lib/test/test_inspect/test_inspect.py
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 1eaf1cc5d9a68e..892f5ba9a7624e 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -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
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index d95f1848ad6d86..1ccfa329d5546a 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -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
----
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 0c33c6cc995a03..ea0d992436eb17 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -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
@@ -128,6 +128,7 @@
"ismethoddescriptor",
"ismethodwrapper",
"ismodule",
+ "ispackage",
"isroutine",
"istraceback",
"markcoroutinefunction",
@@ -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.
diff --git a/Lib/test/test_inspect/test_inspect.py
b/Lib/test/test_inspect/test_inspect.py
index 77fdc6f238437e..a4857dadec2d5c 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -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
@@ -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,
@@ -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",))
@@ -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)
diff --git
a/Misc/NEWS.d/next/Library/2024-10-17-04-52-00.gh-issue-125633.lMck06.rst
b/Misc/NEWS.d/next/Library/2024-10-17-04-52-00.gh-issue-125633.lMck06.rst
new file mode 100644
index 00000000000000..e816a13b75e0c7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-17-04-52-00.gh-issue-125633.lMck06.rst
@@ -0,0 +1,2 @@
+Add function :func:`inspect.ispackage` to determine whether an object is a
+:term:`package` or not.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]