We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Deprecation Warning: formatargspec
In the new version of Pyomo (3.6.7) an error/warning occurs: `DeprecationWarning: 'formatargspec' is deprecated since Python 3.5. Use 'signature' and the 'Signature' object directly`

This refers to this method: https://github.com/Pyomo/pyomo/blob/master/pyomo/core/base/util.py#L57
Deprecation Warning: formatargspec
In the new version of Pyomo (3.6.7) an error/warning occurs: `DeprecationWarning: 'formatargspec' is deprecated since Python 3.5. Use 'signature' and the 'Signature' object directly`

This refers to this method: https://github.com/Pyomo/pyomo/blob/master/pyomo/core/base/util.py#L57

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pyomo/core/base/util.py`
Content:
```
1 #  ___________________________________________________________________________
2 #
3 #  Pyomo: Python Optimization Modeling Objects
4 #  Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC
5 #  Under the terms of Contract DE-NA0003525 with National Technology and 
6 #  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain 
7 #  rights in this software.
8 #  This software is distributed under the 3-clause BSD License.
9 #  ___________________________________________________________________________
10 
11 #
12 # Utility functions
13 #
14 import collections
15 import functools
16 import inspect
17 import six
18 
19 from six import iteritems
20 
21 if six.PY2:
22     getargspec = inspect.getargspec
23 else:
24     # For our needs, getfullargspec is a drop-in replacement for
25     # getargspec (which was removed in Python 3.x)
26     getargspec = inspect.getfullargspec
27 
28 from pyomo.common import DeveloperError
29 from pyomo.core.expr.numvalue import (
30     native_types,
31 )
32 
33 def is_functor(obj):
34     """
35     Returns true iff obj.__call__ is defined.
36     """
37     return inspect.isfunction(obj) or hasattr(obj,'__call__')
38 
39 
40 #
41 # The following decorator is general and should probably be promoted to
42 # component.py so that we can efficiently handle construction errors on
43 # scalar components.
44 #
45 def _disable_method(fcn, msg=None):
46     if msg is None:
47         msg = 'access %s on' % (fcn.__name__,)
48     def impl(self, *args, **kwds):
49         raise RuntimeError(
50             "Cannot %s %s '%s' before it has been constructed (initialized)."
51             % (msg, type(self).__name__, self.name))
52 
53     # functools.wraps doesn't preserve the function signature until
54     # Python 3.4.  For backwards compatability with Python 2.x, we will
55     # create a temporary (lambda) function using eval that matches the
56     # function signature passed in and calls the generic impl() function
57     args = inspect.formatargspec(*getargspec(fcn))
58     impl_args = eval('lambda %s: impl%s' % (args[1:-1], args), {'impl': impl})
59     return functools.wraps(fcn)(impl_args)
60 
61 def _disable_property(fcn, msg=None):
62     if msg is None:
63         _gmsg = 'access property %s on' % (fcn.fget.__name__,)
64     else:
65         _gmsg = msg
66     def getter(self, *args, **kwds):
67         raise RuntimeError(
68             "Cannot %s %s '%s' before it has been constructed (initialized)."
69             % (_gmsg, type(self).__name__, self.name))
70 
71     if msg is None:
72         _smsg = 'set property %s on' % (fcn.fget.__name__,)
73     else:
74         _smsg = msg
75     def setter(self, *args, **kwds):
76         raise RuntimeError(
77             "Cannot %s %s '%s' before it has been constructed (initialized)."
78             % (_smsg, type(self).__name__, self.name))
79 
80     return property(fget=getter, fset=setter, doc=fcn.__doc__)
81 
82 def disable_methods(methods):
83     """Class decorator to disable methods before construct is called.
84 
85     This decorator should be called to create "Abstract" scalar classes
86     that override key methods to raise exceptions.  When the construct()
87     method is called, the class instance changes type back to the
88     original scalar component and the full class functionality is
89     restored.  The prevents most class methods from having to begin with
90     "`if not self.parent_component()._constructed: raise RuntimeError`"
91     """
92     def class_decorator(cls):
93         assert(len(cls.__bases__) == 1)
94         base = cls.__bases__[0]
95 
96         def construct(self, data=None):
97             self.__class__ = base
98             return base.construct(self, data)
99         construct.__doc__ = base.construct.__doc__
100         cls.construct = construct
101 
102         for method in methods:
103             if type(method) is tuple:
104                 method, msg = method
105             else:
106                 msg = None
107             if not hasattr(base, method):
108                 raise DeveloperError(
109                     "Cannot disable method %s on %s: not present on base class"
110                     % (method, cls))
111             base_method = getattr(base, method)
112             if type(base_method) is property:
113                 setattr(cls, method, _disable_property(base_method, msg))
114             else:
115                 setattr(cls, method, _disable_method(base_method, msg))
116         return cls
117 
118     return class_decorator
119 
120 
121 #
122 # The following set of "Initializer" classes are a general functionality
123 # and should be promoted to their own module so that we can use them on
124 # all Components to standardize how we process component arguments.
125 #
126 def Initializer(init,
127                 allow_generators=False,
128                 treat_sequences_as_mappings=True,
129                 arg_not_specified=None):
130     if init.__class__ in native_types:
131         if init is arg_not_specified:
132             return None
133         return ConstantInitializer(init)
134     elif inspect.isfunction(init):
135         if not allow_generators and inspect.isgeneratorfunction(init):
136             raise ValueError("Generator functions are not allowed")
137         # Historically pyomo.core.base.misc.apply_indexed_rule
138         # accepted rules that took only the parent block (even for
139         # indexed components).  We will preserve that functionality
140         # here.
141         _args = getargspec(init)
142         if len(_args.args) == 1 and _args.varargs is None:
143             return ScalarCallInitializer(init)
144         else:
145             return IndexedCallInitializer(init)
146     elif isinstance(init, collections.Mapping):
147         return ItemInitializer(init)
148     elif isinstance(init, collections.Sequence) \
149             and not isinstance(init, six.string_types):
150         if treat_sequences_as_mappings:
151             return ItemInitializer(init)
152         else:
153             return ConstantInitializer(init)
154     elif inspect.isgenerator(init) or hasattr(init, 'next') \
155          or hasattr(init, '__next__'):
156         if not allow_generators:
157             raise ValueError("Generators are not allowed")
158         return ConstantInitializer(init)
159     else:
160         return ConstantInitializer(init)
161 
162 class InitializerBase(object):
163     __slots__ = ()
164 
165     verified = False
166 
167     def __getstate__(self):
168         return dict((k, getattr(self,k)) for k in self.__slots__)
169 
170     def __setstate__(self, state):
171         for key, val in iteritems(state):
172             object.__setattr__(self, key, val)
173 
174 class ConstantInitializer(InitializerBase):
175     __slots__ = ('val','verified')
176 
177     def __init__(self, val):
178         self.val = val
179         self.verified = False
180 
181     def __call__(self, parent, idx):
182         return self.val
183 
184     def constant(self):
185         return True
186 
187 class ItemInitializer(InitializerBase):
188     __slots__ = ('_dict',)
189 
190     def __init__(self, _dict):
191         self._dict = _dict
192 
193     def __call__(self, parent, idx):
194         return self._dict[idx]
195 
196     def constant(self):
197         return False
198 
199 class IndexedCallInitializer(InitializerBase):
200     __slots__ = ('_fcn',)
201 
202     def __init__(self, _fcn):
203         self._fcn = _fcn
204 
205     def __call__(self, parent, idx):
206         # Note: this is called by a component using data from a Set (so
207         # any tuple-like type should have already been checked and
208         # converted to a tuple; or flattening is turned off and it is
209         # the user's responsibility to sort things out.
210         if idx.__class__ is tuple:
211             return self._fcn(parent, *idx)
212         else:
213             return self._fcn(parent, idx)
214 
215     def constant(self):
216         return False
217 
218 
219 class CountedCallGenerator(object):
220     def __init__(self, fcn, scalar, parent, idx):
221         # Note: this is called by a component using data from a Set (so
222         # any tuple-like type should have already been checked and
223         # converted to a tuple; or flattening is turned off and it is
224         # the user's responsibility to sort things out.
225         self._count = 0
226         if scalar:
227             self._fcn = lambda c: self._filter(fcn(parent, c))
228         elif idx.__class__ is tuple:
229             self._fcn = lambda c: self._filter(fcn(parent, c, *idx))
230         else:
231             self._fcn = lambda c: self._filter(fcn(parent, c, idx))
232 
233     def __iter__(self):
234         return self
235 
236     def __next__(self):
237         self._count += 1
238         return self._fcn(self._count)
239 
240     @staticmethod
241     def _filter(x):
242         if x is None:
243             raise ValueError(
244                 """Counted Set rule returned None instead of Set.End.
245     Counted Set rules of the form fcn(model, count, *idx) will be called
246     repeatedly with an increasing count parameter until the rule returns
247     Set.End.  None is not a valid Set member in this case due to the
248     likelihood that an error in the rule can incorrectly return None.""")
249         return x
250 
251 
252     next = __next__
253 
254 
255 class CountedCallInitializer(InitializerBase):
256     # Pyomo has a historical feature for some rules, where the number of
257     # times[*1] the rule was called could be passed as an additional
258     # argument between the block and the index.  This was primarily
259     # supported by Set and ConstraintList.  There were many issues with
260     # the syntax, including inconsistent support for jagged (dimen=None)
261     # indexing sets, inconsistent support for *args rules, and a likely
262     # infinite loop if the rule returned Constraint.Skip.
263     #
264     # As a slight departure from previous implementations, we will ONLY
265     # allow the counted rule syntax when the rule does NOT use *args
266     #
267     # [*1] The extra argument was one-based, and was only incremented
268     #     when a valid value was returned by the rule and added to the
269     #     _data.  This was fragile, as returning something like
270     #     {Component}.Skip could result in an infinite loop.  This
271     #     implementation deviates from that behavior and increments the
272     #     counter every time the rule is called.
273     #
274     # [JDS 6/2019] We will support a slightly restricted but more
275     # consistent form of the original implementation for backwards
276     # compatability, but I believe that we should deprecate this syntax
277     # entirely.
278     __slots__ = ('_fcn','_is_counted_rule', '_scalar',)
279 
280     def __init__(self, obj, _indexed_init):
281         self._fcn = _indexed_init._fcn
282         self._is_counted_rule = None
283         self._scalar = not obj.is_indexed()
284         if self._scalar:
285             self._is_counted_rule = True
286 
287     def __call__(self, parent, idx):
288         # Note: this is called by a component using data from a Set (so
289         # any tuple-like type should have already been checked and
290         # converted to a tuple; or flattening is turned off and it is
291         # the user's responsibility to sort things out.
292         if self._is_counted_rule == False:
293             if idx.__class__ is tuple:
294                 return self._fcn(parent, *idx)
295             else:
296                 return self._fcn(parent, idx)
297         if self._is_counted_rule == True:
298             return CountedCallGenerator(self._fcn, self._scalar, parent, idx)
299 
300         # Note that this code will only be called once, and only if
301         # the object is not a scalar.
302         _args = getargspec(self._fcn)
303         _len = len(idx) if idx.__class__ is tuple else 1
304         if _len + 2 == len(_args.args):
305             self._is_counted_rule = True
306         else:
307             self._is_counted_rule = False
308         return self.__call__(parent, idx)
309 
310     def constant(self):
311         return False
312 
313 class ScalarCallInitializer(InitializerBase):
314     __slots__ = ('_fcn',)
315 
316     def __init__(self, _fcn):
317         self._fcn = _fcn
318 
319     def __call__(self, parent, idx):
320         return self._fcn(parent)
321 
322     def constant(self):
323         return False
324 
325
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pyomo/core/base/util.py b/pyomo/core/base/util.py
--- a/pyomo/core/base/util.py
+++ b/pyomo/core/base/util.py
@@ -42,21 +42,41 @@
 # component.py so that we can efficiently handle construction errors on
 # scalar components.
 #
+# TODO: quantify the memory overhead here.  We create (and preserve) a
+# locals() dict for *each* method that we wrap.  If that becomes
+# significant, we might consider using a single global private
+# environment (which would require some thought when managing any
+# potential name collisions)
+#
 def _disable_method(fcn, msg=None):
+    _name = fcn.__name__
     if msg is None:
-        msg = 'access %s on' % (fcn.__name__,)
-    def impl(self, *args, **kwds):
-        raise RuntimeError(
-            "Cannot %s %s '%s' before it has been constructed (initialized)."
-            % (msg, type(self).__name__, self.name))
+        msg = 'access %s on' % (_name,)
 
     # functools.wraps doesn't preserve the function signature until
-    # Python 3.4.  For backwards compatability with Python 2.x, we will
-    # create a temporary (lambda) function using eval that matches the
-    # function signature passed in and calls the generic impl() function
-    args = inspect.formatargspec(*getargspec(fcn))
-    impl_args = eval('lambda %s: impl%s' % (args[1:-1], args), {'impl': impl})
-    return functools.wraps(fcn)(impl_args)
+    # Python 3.4, and even then, does not preserve it accurately (e.g.,
+    # calling with the incorreect number of arguments does not generate
+    # an error).  For backwards compatability with Python 2.x, we will
+    # create a temporary (local) function using exec that matches the
+    # function signature passed in and raises an exception
+    if six.PY2:
+        args = str(inspect.formatargspec(*getargspec(fcn)))
+    else:
+        args = str(inspect.signature(fcn))
+    assert args == '(self)' or args.startswith('(self,')
+
+    # lambda comes through with a function name "<lambda>".  We will
+    # use exec here to create a function (in a private namespace)
+    # that will have the correct name.
+    _env = {}
+    _funcdef = """def %s%s:
+        raise RuntimeError(
+            "Cannot %s %%s '%%s' before it has been constructed (initialized)."
+            %% (type(self).__name__, self.name))
+""" % (_name, args, msg,)
+    exec(_funcdef, _env)
+    return functools.wraps(fcn)(_env[_name])
+
 
 def _disable_property(fcn, msg=None):
     if msg is None:

{"golden_diff": "diff --git a/pyomo/core/base/util.py b/pyomo/core/base/util.py\n--- a/pyomo/core/base/util.py\n+++ b/pyomo/core/base/util.py\n@@ -42,21 +42,41 @@\n # component.py so that we can efficiently handle construction errors on\n # scalar components.\n #\n+# TODO: quantify the memory overhead here.  We create (and preserve) a\n+# locals() dict for *each* method that we wrap.  If that becomes\n+# significant, we might consider using a single global private\n+# environment (which would require some thought when managing any\n+# potential name collisions)\n+#\n def _disable_method(fcn, msg=None):\n+    _name = fcn.__name__\n     if msg is None:\n-        msg = 'access %s on' % (fcn.__name__,)\n-    def impl(self, *args, **kwds):\n-        raise RuntimeError(\n-            \"Cannot %s %s '%s' before it has been constructed (initialized).\"\n-            % (msg, type(self).__name__, self.name))\n+        msg = 'access %s on' % (_name,)\n \n     # functools.wraps doesn't preserve the function signature until\n-    # Python 3.4.  For backwards compatability with Python 2.x, we will\n-    # create a temporary (lambda) function using eval that matches the\n-    # function signature passed in and calls the generic impl() function\n-    args = inspect.formatargspec(*getargspec(fcn))\n-    impl_args = eval('lambda %s: impl%s' % (args[1:-1], args), {'impl': impl})\n-    return functools.wraps(fcn)(impl_args)\n+    # Python 3.4, and even then, does not preserve it accurately (e.g.,\n+    # calling with the incorreect number of arguments does not generate\n+    # an error).  For backwards compatability with Python 2.x, we will\n+    # create a temporary (local) function using exec that matches the\n+    # function signature passed in and raises an exception\n+    if six.PY2:\n+        args = str(inspect.formatargspec(*getargspec(fcn)))\n+    else:\n+        args = str(inspect.signature(fcn))\n+    assert args == '(self)' or args.startswith('(self,')\n+\n+    # lambda comes through with a function name \"<lambda>\".  We will\n+    # use exec here to create a function (in a private namespace)\n+    # that will have the correct name.\n+    _env = {}\n+    _funcdef = \"\"\"def %s%s:\n+        raise RuntimeError(\n+            \"Cannot %s %%s '%%s' before it has been constructed (initialized).\"\n+            %% (type(self).__name__, self.name))\n+\"\"\" % (_name, args, msg,)\n+    exec(_funcdef, _env)\n+    return functools.wraps(fcn)(_env[_name])\n+\n \n def _disable_property(fcn, msg=None):\n     if msg is None:\n", "issue": "Deprecation Warning: formatargspec\nIn the new version of Pyomo (3.6.7) an error/warning occurs: `DeprecationWarning: 'formatargspec' is deprecated since Python 3.5. Use 'signature' and the 'Signature' object directly`\r\n\r\nThis refers to this method: https://github.com/Pyomo/pyomo/blob/master/pyomo/core/base/util.py#L57\nDeprecation Warning: formatargspec\nIn the new version of Pyomo (3.6.7) an error/warning occurs: `DeprecationWarning: 'formatargspec' is deprecated since Python 3.5. Use 'signature' and the 'Signature' object directly`\r\n\r\nThis refers to this method: https://github.com/Pyomo/pyomo/blob/master/pyomo/core/base/util.py#L57\n", "before_files": [{"content": "#  ___________________________________________________________________________\n#\n#  Pyomo: Python Optimization Modeling Objects\n#  Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC\n#  Under the terms of Contract DE-NA0003525 with National Technology and \n#  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain \n#  rights in this software.\n#  This software is distributed under the 3-clause BSD License.\n#  ___________________________________________________________________________\n\n#\n# Utility functions\n#\nimport collections\nimport functools\nimport inspect\nimport six\n\nfrom six import iteritems\n\nif six.PY2:\n    getargspec = inspect.getargspec\nelse:\n    # For our needs, getfullargspec is a drop-in replacement for\n    # getargspec (which was removed in Python 3.x)\n    getargspec = inspect.getfullargspec\n\nfrom pyomo.common import DeveloperError\nfrom pyomo.core.expr.numvalue import (\n    native_types,\n)\n\ndef is_functor(obj):\n    \"\"\"\n    Returns true iff obj.__call__ is defined.\n    \"\"\"\n    return inspect.isfunction(obj) or hasattr(obj,'__call__')\n\n\n#\n# The following decorator is general and should probably be promoted to\n# component.py so that we can efficiently handle construction errors on\n# scalar components.\n#\ndef _disable_method(fcn, msg=None):\n    if msg is None:\n        msg = 'access %s on' % (fcn.__name__,)\n    def impl(self, *args, **kwds):\n        raise RuntimeError(\n            \"Cannot %s %s '%s' before it has been constructed (initialized).\"\n            % (msg, type(self).__name__, self.name))\n\n    # functools.wraps doesn't preserve the function signature until\n    # Python 3.4.  For backwards compatability with Python 2.x, we will\n    # create a temporary (lambda) function using eval that matches the\n    # function signature passed in and calls the generic impl() function\n    args = inspect.formatargspec(*getargspec(fcn))\n    impl_args = eval('lambda %s: impl%s' % (args[1:-1], args), {'impl': impl})\n    return functools.wraps(fcn)(impl_args)\n\ndef _disable_property(fcn, msg=None):\n    if msg is None:\n        _gmsg = 'access property %s on' % (fcn.fget.__name__,)\n    else:\n        _gmsg = msg\n    def getter(self, *args, **kwds):\n        raise RuntimeError(\n            \"Cannot %s %s '%s' before it has been constructed (initialized).\"\n            % (_gmsg, type(self).__name__, self.name))\n\n    if msg is None:\n        _smsg = 'set property %s on' % (fcn.fget.__name__,)\n    else:\n        _smsg = msg\n    def setter(self, *args, **kwds):\n        raise RuntimeError(\n            \"Cannot %s %s '%s' before it has been constructed (initialized).\"\n            % (_smsg, type(self).__name__, self.name))\n\n    return property(fget=getter, fset=setter, doc=fcn.__doc__)\n\ndef disable_methods(methods):\n    \"\"\"Class decorator to disable methods before construct is called.\n\n    This decorator should be called to create \"Abstract\" scalar classes\n    that override key methods to raise exceptions.  When the construct()\n    method is called, the class instance changes type back to the\n    original scalar component and the full class functionality is\n    restored.  The prevents most class methods from having to begin with\n    \"`if not self.parent_component()._constructed: raise RuntimeError`\"\n    \"\"\"\n    def class_decorator(cls):\n        assert(len(cls.__bases__) == 1)\n        base = cls.__bases__[0]\n\n        def construct(self, data=None):\n            self.__class__ = base\n            return base.construct(self, data)\n        construct.__doc__ = base.construct.__doc__\n        cls.construct = construct\n\n        for method in methods:\n            if type(method) is tuple:\n                method, msg = method\n            else:\n                msg = None\n            if not hasattr(base, method):\n                raise DeveloperError(\n                    \"Cannot disable method %s on %s: not present on base class\"\n                    % (method, cls))\n            base_method = getattr(base, method)\n            if type(base_method) is property:\n                setattr(cls, method, _disable_property(base_method, msg))\n            else:\n                setattr(cls, method, _disable_method(base_method, msg))\n        return cls\n\n    return class_decorator\n\n\n#\n# The following set of \"Initializer\" classes are a general functionality\n# and should be promoted to their own module so that we can use them on\n# all Components to standardize how we process component arguments.\n#\ndef Initializer(init,\n                allow_generators=False,\n                treat_sequences_as_mappings=True,\n                arg_not_specified=None):\n    if init.__class__ in native_types:\n        if init is arg_not_specified:\n            return None\n        return ConstantInitializer(init)\n    elif inspect.isfunction(init):\n        if not allow_generators and inspect.isgeneratorfunction(init):\n            raise ValueError(\"Generator functions are not allowed\")\n        # Historically pyomo.core.base.misc.apply_indexed_rule\n        # accepted rules that took only the parent block (even for\n        # indexed components).  We will preserve that functionality\n        # here.\n        _args = getargspec(init)\n        if len(_args.args) == 1 and _args.varargs is None:\n            return ScalarCallInitializer(init)\n        else:\n            return IndexedCallInitializer(init)\n    elif isinstance(init, collections.Mapping):\n        return ItemInitializer(init)\n    elif isinstance(init, collections.Sequence) \\\n            and not isinstance(init, six.string_types):\n        if treat_sequences_as_mappings:\n            return ItemInitializer(init)\n        else:\n            return ConstantInitializer(init)\n    elif inspect.isgenerator(init) or hasattr(init, 'next') \\\n         or hasattr(init, '__next__'):\n        if not allow_generators:\n            raise ValueError(\"Generators are not allowed\")\n        return ConstantInitializer(init)\n    else:\n        return ConstantInitializer(init)\n\nclass InitializerBase(object):\n    __slots__ = ()\n\n    verified = False\n\n    def __getstate__(self):\n        return dict((k, getattr(self,k)) for k in self.__slots__)\n\n    def __setstate__(self, state):\n        for key, val in iteritems(state):\n            object.__setattr__(self, key, val)\n\nclass ConstantInitializer(InitializerBase):\n    __slots__ = ('val','verified')\n\n    def __init__(self, val):\n        self.val = val\n        self.verified = False\n\n    def __call__(self, parent, idx):\n        return self.val\n\n    def constant(self):\n        return True\n\nclass ItemInitializer(InitializerBase):\n    __slots__ = ('_dict',)\n\n    def __init__(self, _dict):\n        self._dict = _dict\n\n    def __call__(self, parent, idx):\n        return self._dict[idx]\n\n    def constant(self):\n        return False\n\nclass IndexedCallInitializer(InitializerBase):\n    __slots__ = ('_fcn',)\n\n    def __init__(self, _fcn):\n        self._fcn = _fcn\n\n    def __call__(self, parent, idx):\n        # Note: this is called by a component using data from a Set (so\n        # any tuple-like type should have already been checked and\n        # converted to a tuple; or flattening is turned off and it is\n        # the user's responsibility to sort things out.\n        if idx.__class__ is tuple:\n            return self._fcn(parent, *idx)\n        else:\n            return self._fcn(parent, idx)\n\n    def constant(self):\n        return False\n\n\nclass CountedCallGenerator(object):\n    def __init__(self, fcn, scalar, parent, idx):\n        # Note: this is called by a component using data from a Set (so\n        # any tuple-like type should have already been checked and\n        # converted to a tuple; or flattening is turned off and it is\n        # the user's responsibility to sort things out.\n        self._count = 0\n        if scalar:\n            self._fcn = lambda c: self._filter(fcn(parent, c))\n        elif idx.__class__ is tuple:\n            self._fcn = lambda c: self._filter(fcn(parent, c, *idx))\n        else:\n            self._fcn = lambda c: self._filter(fcn(parent, c, idx))\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        self._count += 1\n        return self._fcn(self._count)\n\n    @staticmethod\n    def _filter(x):\n        if x is None:\n            raise ValueError(\n                \"\"\"Counted Set rule returned None instead of Set.End.\n    Counted Set rules of the form fcn(model, count, *idx) will be called\n    repeatedly with an increasing count parameter until the rule returns\n    Set.End.  None is not a valid Set member in this case due to the\n    likelihood that an error in the rule can incorrectly return None.\"\"\")\n        return x\n\n\n    next = __next__\n\n\nclass CountedCallInitializer(InitializerBase):\n    # Pyomo has a historical feature for some rules, where the number of\n    # times[*1] the rule was called could be passed as an additional\n    # argument between the block and the index.  This was primarily\n    # supported by Set and ConstraintList.  There were many issues with\n    # the syntax, including inconsistent support for jagged (dimen=None)\n    # indexing sets, inconsistent support for *args rules, and a likely\n    # infinite loop if the rule returned Constraint.Skip.\n    #\n    # As a slight departure from previous implementations, we will ONLY\n    # allow the counted rule syntax when the rule does NOT use *args\n    #\n    # [*1] The extra argument was one-based, and was only incremented\n    #     when a valid value was returned by the rule and added to the\n    #     _data.  This was fragile, as returning something like\n    #     {Component}.Skip could result in an infinite loop.  This\n    #     implementation deviates from that behavior and increments the\n    #     counter every time the rule is called.\n    #\n    # [JDS 6/2019] We will support a slightly restricted but more\n    # consistent form of the original implementation for backwards\n    # compatability, but I believe that we should deprecate this syntax\n    # entirely.\n    __slots__ = ('_fcn','_is_counted_rule', '_scalar',)\n\n    def __init__(self, obj, _indexed_init):\n        self._fcn = _indexed_init._fcn\n        self._is_counted_rule = None\n        self._scalar = not obj.is_indexed()\n        if self._scalar:\n            self._is_counted_rule = True\n\n    def __call__(self, parent, idx):\n        # Note: this is called by a component using data from a Set (so\n        # any tuple-like type should have already been checked and\n        # converted to a tuple; or flattening is turned off and it is\n        # the user's responsibility to sort things out.\n        if self._is_counted_rule == False:\n            if idx.__class__ is tuple:\n                return self._fcn(parent, *idx)\n            else:\n                return self._fcn(parent, idx)\n        if self._is_counted_rule == True:\n            return CountedCallGenerator(self._fcn, self._scalar, parent, idx)\n\n        # Note that this code will only be called once, and only if\n        # the object is not a scalar.\n        _args = getargspec(self._fcn)\n        _len = len(idx) if idx.__class__ is tuple else 1\n        if _len + 2 == len(_args.args):\n            self._is_counted_rule = True\n        else:\n            self._is_counted_rule = False\n        return self.__call__(parent, idx)\n\n    def constant(self):\n        return False\n\nclass ScalarCallInitializer(InitializerBase):\n    __slots__ = ('_fcn',)\n\n    def __init__(self, _fcn):\n        self._fcn = _fcn\n\n    def __call__(self, parent, idx):\n        return self._fcn(parent)\n\n    def constant(self):\n        return False\n\n", "path": "pyomo/core/base/util.py"}], "after_files": [{"content": "#  ___________________________________________________________________________\n#\n#  Pyomo: Python Optimization Modeling Objects\n#  Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC\n#  Under the terms of Contract DE-NA0003525 with National Technology and \n#  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain \n#  rights in this software.\n#  This software is distributed under the 3-clause BSD License.\n#  ___________________________________________________________________________\n\n#\n# Utility functions\n#\nimport collections\nimport functools\nimport inspect\nimport six\n\nfrom six import iteritems\n\nif six.PY2:\n    getargspec = inspect.getargspec\nelse:\n    # For our needs, getfullargspec is a drop-in replacement for\n    # getargspec (which was removed in Python 3.x)\n    getargspec = inspect.getfullargspec\n\nfrom pyomo.common import DeveloperError\nfrom pyomo.core.expr.numvalue import (\n    native_types,\n)\n\ndef is_functor(obj):\n    \"\"\"\n    Returns true iff obj.__call__ is defined.\n    \"\"\"\n    return inspect.isfunction(obj) or hasattr(obj,'__call__')\n\n\n#\n# The following decorator is general and should probably be promoted to\n# component.py so that we can efficiently handle construction errors on\n# scalar components.\n#\n# TODO: quantify the memory overhead here.  We create (and preserve) a\n# locals() dict for *each* method that we wrap.  If that becomes\n# significant, we might consider using a single global private\n# environment (which would require some thought when managing any\n# potential name collisions)\n#\ndef _disable_method(fcn, msg=None):\n    _name = fcn.__name__\n    if msg is None:\n        msg = 'access %s on' % (_name,)\n\n    # functools.wraps doesn't preserve the function signature until\n    # Python 3.4, and even then, does not preserve it accurately (e.g.,\n    # calling with the incorreect number of arguments does not generate\n    # an error).  For backwards compatability with Python 2.x, we will\n    # create a temporary (local) function using exec that matches the\n    # function signature passed in and raises an exception\n    if six.PY2:\n        args = str(inspect.formatargspec(*getargspec(fcn)))\n    else:\n        args = str(inspect.signature(fcn))\n    assert args == '(self)' or args.startswith('(self,')\n\n    # lambda comes through with a function name \"<lambda>\".  We will\n    # use exec here to create a function (in a private namespace)\n    # that will have the correct name.\n    _env = {}\n    _funcdef = \"\"\"def %s%s:\n        raise RuntimeError(\n            \"Cannot %s %%s '%%s' before it has been constructed (initialized).\"\n            %% (type(self).__name__, self.name))\n\"\"\" % (_name, args, msg,)\n    exec(_funcdef, _env)\n    return functools.wraps(fcn)(_env[_name])\n\n\ndef _disable_property(fcn, msg=None):\n    if msg is None:\n        _gmsg = 'access property %s on' % (fcn.fget.__name__,)\n    else:\n        _gmsg = msg\n    def getter(self, *args, **kwds):\n        raise RuntimeError(\n            \"Cannot %s %s '%s' before it has been constructed (initialized).\"\n            % (_gmsg, type(self).__name__, self.name))\n\n    if msg is None:\n        _smsg = 'set property %s on' % (fcn.fget.__name__,)\n    else:\n        _smsg = msg\n    def setter(self, *args, **kwds):\n        raise RuntimeError(\n            \"Cannot %s %s '%s' before it has been constructed (initialized).\"\n            % (_smsg, type(self).__name__, self.name))\n\n    return property(fget=getter, fset=setter, doc=fcn.__doc__)\n\ndef disable_methods(methods):\n    \"\"\"Class decorator to disable methods before construct is called.\n\n    This decorator should be called to create \"Abstract\" scalar classes\n    that override key methods to raise exceptions.  When the construct()\n    method is called, the class instance changes type back to the\n    original scalar component and the full class functionality is\n    restored.  The prevents most class methods from having to begin with\n    \"`if not self.parent_component()._constructed: raise RuntimeError`\"\n    \"\"\"\n    def class_decorator(cls):\n        assert(len(cls.__bases__) == 1)\n        base = cls.__bases__[0]\n\n        def construct(self, data=None):\n            self.__class__ = base\n            return base.construct(self, data)\n        construct.__doc__ = base.construct.__doc__\n        cls.construct = construct\n\n        for method in methods:\n            if type(method) is tuple:\n                method, msg = method\n            else:\n                msg = None\n            if not hasattr(base, method):\n                raise DeveloperError(\n                    \"Cannot disable method %s on %s: not present on base class\"\n                    % (method, cls))\n            base_method = getattr(base, method)\n            if type(base_method) is property:\n                setattr(cls, method, _disable_property(base_method, msg))\n            else:\n                setattr(cls, method, _disable_method(base_method, msg))\n        return cls\n\n    return class_decorator\n\n\n#\n# The following set of \"Initializer\" classes are a general functionality\n# and should be promoted to their own module so that we can use them on\n# all Components to standardize how we process component arguments.\n#\ndef Initializer(init,\n                allow_generators=False,\n                treat_sequences_as_mappings=True,\n                arg_not_specified=None):\n    if init.__class__ in native_types:\n        if init is arg_not_specified:\n            return None\n        return ConstantInitializer(init)\n    elif inspect.isfunction(init):\n        if not allow_generators and inspect.isgeneratorfunction(init):\n            raise ValueError(\"Generator functions are not allowed\")\n        # Historically pyomo.core.base.misc.apply_indexed_rule\n        # accepted rules that took only the parent block (even for\n        # indexed components).  We will preserve that functionality\n        # here.\n        _args = getargspec(init)\n        if len(_args.args) == 1 and _args.varargs is None:\n            return ScalarCallInitializer(init)\n        else:\n            return IndexedCallInitializer(init)\n    elif isinstance(init, collections.Mapping):\n        return ItemInitializer(init)\n    elif isinstance(init, collections.Sequence) \\\n            and not isinstance(init, six.string_types):\n        if treat_sequences_as_mappings:\n            return ItemInitializer(init)\n        else:\n            return ConstantInitializer(init)\n    elif inspect.isgenerator(init) or hasattr(init, 'next') \\\n         or hasattr(init, '__next__'):\n        if not allow_generators:\n            raise ValueError(\"Generators are not allowed\")\n        return ConstantInitializer(init)\n    else:\n        return ConstantInitializer(init)\n\nclass InitializerBase(object):\n    __slots__ = ()\n\n    verified = False\n\n    def __getstate__(self):\n        return dict((k, getattr(self,k)) for k in self.__slots__)\n\n    def __setstate__(self, state):\n        for key, val in iteritems(state):\n            object.__setattr__(self, key, val)\n\nclass ConstantInitializer(InitializerBase):\n    __slots__ = ('val','verified')\n\n    def __init__(self, val):\n        self.val = val\n        self.verified = False\n\n    def __call__(self, parent, idx):\n        return self.val\n\n    def constant(self):\n        return True\n\nclass ItemInitializer(InitializerBase):\n    __slots__ = ('_dict',)\n\n    def __init__(self, _dict):\n        self._dict = _dict\n\n    def __call__(self, parent, idx):\n        return self._dict[idx]\n\n    def constant(self):\n        return False\n\nclass IndexedCallInitializer(InitializerBase):\n    __slots__ = ('_fcn',)\n\n    def __init__(self, _fcn):\n        self._fcn = _fcn\n\n    def __call__(self, parent, idx):\n        # Note: this is called by a component using data from a Set (so\n        # any tuple-like type should have already been checked and\n        # converted to a tuple; or flattening is turned off and it is\n        # the user's responsibility to sort things out.\n        if idx.__class__ is tuple:\n            return self._fcn(parent, *idx)\n        else:\n            return self._fcn(parent, idx)\n\n    def constant(self):\n        return False\n\n\nclass CountedCallGenerator(object):\n    def __init__(self, fcn, scalar, parent, idx):\n        # Note: this is called by a component using data from a Set (so\n        # any tuple-like type should have already been checked and\n        # converted to a tuple; or flattening is turned off and it is\n        # the user's responsibility to sort things out.\n        self._count = 0\n        if scalar:\n            self._fcn = lambda c: self._filter(fcn(parent, c))\n        elif idx.__class__ is tuple:\n            self._fcn = lambda c: self._filter(fcn(parent, c, *idx))\n        else:\n            self._fcn = lambda c: self._filter(fcn(parent, c, idx))\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        self._count += 1\n        return self._fcn(self._count)\n\n    @staticmethod\n    def _filter(x):\n        if x is None:\n            raise ValueError(\n                \"\"\"Counted Set rule returned None instead of Set.End.\n    Counted Set rules of the form fcn(model, count, *idx) will be called\n    repeatedly with an increasing count parameter until the rule returns\n    Set.End.  None is not a valid Set member in this case due to the\n    likelihood that an error in the rule can incorrectly return None.\"\"\")\n        return x\n\n\n    next = __next__\n\n\nclass CountedCallInitializer(InitializerBase):\n    # Pyomo has a historical feature for some rules, where the number of\n    # times[*1] the rule was called could be passed as an additional\n    # argument between the block and the index.  This was primarily\n    # supported by Set and ConstraintList.  There were many issues with\n    # the syntax, including inconsistent support for jagged (dimen=None)\n    # indexing sets, inconsistent support for *args rules, and a likely\n    # infinite loop if the rule returned Constraint.Skip.\n    #\n    # As a slight departure from previous implementations, we will ONLY\n    # allow the counted rule syntax when the rule does NOT use *args\n    #\n    # [*1] The extra argument was one-based, and was only incremented\n    #     when a valid value was returned by the rule and added to the\n    #     _data.  This was fragile, as returning something like\n    #     {Component}.Skip could result in an infinite loop.  This\n    #     implementation deviates from that behavior and increments the\n    #     counter every time the rule is called.\n    #\n    # [JDS 6/2019] We will support a slightly restricted but more\n    # consistent form of the original implementation for backwards\n    # compatability, but I believe that we should deprecate this syntax\n    # entirely.\n    __slots__ = ('_fcn','_is_counted_rule', '_scalar',)\n\n    def __init__(self, obj, _indexed_init):\n        self._fcn = _indexed_init._fcn\n        self._is_counted_rule = None\n        self._scalar = not obj.is_indexed()\n        if self._scalar:\n            self._is_counted_rule = True\n\n    def __call__(self, parent, idx):\n        # Note: this is called by a component using data from a Set (so\n        # any tuple-like type should have already been checked and\n        # converted to a tuple; or flattening is turned off and it is\n        # the user's responsibility to sort things out.\n        if self._is_counted_rule == False:\n            if idx.__class__ is tuple:\n                return self._fcn(parent, *idx)\n            else:\n                return self._fcn(parent, idx)\n        if self._is_counted_rule == True:\n            return CountedCallGenerator(self._fcn, self._scalar, parent, idx)\n\n        # Note that this code will only be called once, and only if\n        # the object is not a scalar.\n        _args = getargspec(self._fcn)\n        _len = len(idx) if idx.__class__ is tuple else 1\n        if _len + 2 == len(_args.args):\n            self._is_counted_rule = True\n        else:\n            self._is_counted_rule = False\n        return self.__call__(parent, idx)\n\n    def constant(self):\n        return False\n\nclass ScalarCallInitializer(InitializerBase):\n    __slots__ = ('_fcn',)\n\n    def __init__(self, _fcn):\n        self._fcn = _fcn\n\n    def __call__(self, parent, idx):\n        return self._fcn(parent)\n\n    def constant(self):\n        return False\n\n", "path": "pyomo/core/base/util.py"}]}