Skip to content

Commit eab64f1

Browse files
committed
Python: Dataflow, start on test for classes
1 parent 38acea6 commit eab64f1

File tree

1 file changed

+72
-0
lines changed
  • python/ql/test/experimental/dataflow/coverage

1 file changed

+72
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# These are included so that we can easily evaluate the test code
2+
SOURCE = "source"
3+
def SINK(x):
4+
print(x)
5+
6+
# Callable types
7+
# These are the types to which the function call operation (see section Calls) can be applied:
8+
9+
# User-defined functions
10+
# A user-defined function object is created by a function definition (see section Function definitions). It should be called with an argument list containing the same number of items as the function's formal parameter list.
11+
def f(a, b):
12+
return a
13+
14+
SINK(f(SOURCE, 3))
15+
16+
# Instance methods
17+
# An instance method object combines a class, a class instance and any callable object (normally a user-defined function).
18+
class C(object):
19+
20+
def method(self, a, cls):
21+
assert cls is self.__class__
22+
return a
23+
24+
@classmethod
25+
def classmethod(cls, a):
26+
return a
27+
28+
@staticmethod
29+
def staticmethod():
30+
return a
31+
32+
c = C()
33+
34+
# When an instance method object is created by retrieving a user-defined function object from a class via one of its instances, its __self__ attribute is the instance, and the method object is said to be bound. The new method’s __func__ attribute is the original function object.
35+
func_obj = c.method.__func__
36+
37+
# When an instance method object is called, the underlying function (__func__) is called, inserting the class instance (__self__) in front of the argument list. For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling x.f(1) is equivalent to calling C.f(x, 1).
38+
SINK(c.method(SOURCE, C))
39+
SINK(C.method(c, SOURCE, C))
40+
SINK(func_obj(c, SOURCE, C))
41+
42+
43+
# When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method.
44+
c_func_obj = C.classmethod.__func__
45+
46+
# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function.
47+
SINK(c.classmethod(SOURCE))
48+
SINK(C.classmethod(SOURCE))
49+
SINK(c_func_obj(C, SOURCE))
50+
51+
# Generator functions
52+
# A function or method which uses the yield statement (see section The yield statement) is called a generator function. Such a function, when called, always returns an iterator object which can be used to execute the body of the function: calling the iterator’s iterator.__next__() method will cause the function to execute until it provides a value using the yield statement. When the function executes a return statement or falls off the end, a StopIteration exception is raised and the iterator will have reached the end of the set of values to be returned.
53+
54+
# Coroutine functions
55+
# A function or method which is defined using async def is called a coroutine function. Such a function, when called, returns a coroutine object. It may contain await expressions, as well as async with and async for statements. See also the Coroutine Objects section.
56+
57+
# Asynchronous generator functions
58+
# A function or method which is defined using async def and which uses the yield statement is called a asynchronous generator function. Such a function, when called, returns an asynchronous iterator object which can be used in an async for statement to execute the body of the function.
59+
60+
# Calling the asynchronous iterator’s aiterator.__anext__() method will return an awaitable which when awaited will execute until it provides a value using the yield expression. When the function executes an empty return statement or falls off the end, a StopAsyncIteration exception is raised and the asynchronous iterator will have reached the end of the set of values to be yielded.
61+
62+
# Built-in functions
63+
# A built-in function object is a wrapper around a C function. Examples of built-in functions are len() and math.sin() (math is a standard built-in module). The number and type of the arguments are determined by the C function. Special read-only attributes: __doc__ is the function’s documentation string, or None if unavailable; __name__ is the function’s name; __self__ is set to None (but see the next item); __module__ is the name of the module the function was defined in or None if unavailable.
64+
65+
# Built-in methods
66+
# This is really a different disguise of a built-in function, this time containing an object passed to the C function as an implicit extra argument. An example of a built-in method is alist.append(), assuming alist is a list object. In this case, the special read-only attribute __self__ is set to the object denoted by alist.
67+
68+
# Classes
69+
# Classes are callable. These objects normally act as factories for new instances of themselves, but variations are possible for class types that override __new__(). The arguments of the call are passed to __new__() and, in the typical case, to __init__() to initialize the new instance.
70+
71+
# Class Instances
72+
# Instances of arbitrary classes can be made callable by defining a __call__() method in their class.

0 commit comments

Comments
 (0)