@@ -59,6 +59,18 @@ abstract class ModuleObjectInternal extends ObjectInternal {
5959 /* Modules aren't iterable */
6060 override ObjectInternal getIterNext ( ) { none ( ) }
6161
62+ /** Holds if this module "exports" name.
63+ * That is, does it define `name` in `__all__` or is
64+ * `__all__` not defined and `name` a global variable that does not start with "_"
65+ * This is the set of names imported by `from ... import *`.
66+ */
67+ predicate exports ( string name ) {
68+ not this .( ModuleObjectInternal ) .attribute ( "__all__" , _, _) and this .hasAttribute ( name )
69+ and not name .charAt ( 0 ) = "_"
70+ or
71+ py_exports ( this .getSourceModule ( ) , name )
72+ }
73+
6274}
6375
6476/** A class representing built-in modules */
@@ -209,6 +221,13 @@ class PackageObjectInternal extends ModuleObjectInternal, TPackageObject {
209221 )
210222 }
211223
224+ /** Holds if this value has the attribute `name` */
225+ override predicate hasAttribute ( string name ) {
226+ this .getInitModule ( ) .hasAttribute ( name )
227+ or
228+ exists ( this .submodule ( name ) )
229+ }
230+
212231}
213232
214233/** A class representing Python modules */
@@ -261,6 +280,24 @@ class PythonModuleObjectInternal extends ModuleObjectInternal, TPythonModule {
261280 result = this .getSourceModule ( ) .getEntryNode ( )
262281 }
263282
283+ /** Holds if this value has the attribute `name` */
284+ override predicate hasAttribute ( string name ) {
285+ name = "__name__"
286+ or
287+ this .getSourceModule ( ) .( ImportTimeScope ) .definesName ( name )
288+ or
289+ exists ( ModuleObjectInternal mod , ImportStarNode imp |
290+ PointsToInternal:: pointsTo ( imp , _, mod , _) and
291+ imp .getScope ( ) = this .getSourceModule ( ) and
292+ mod .exports ( name )
293+ )
294+ or
295+ exists ( ObjectInternal defined |
296+ this .attribute ( name , defined , _) and
297+ not defined instanceof UndefinedInternal
298+ )
299+ }
300+
264301}
265302
266303/** A class representing a module that is missing from the DB, but inferred to exists from imports. */
0 commit comments