Using GetMem and VarPtr to get around Object default values [duplicate] - excel

This question already has answers here:
How can I assign a Variant to a Variant in VBA?
(5 answers)
Closed 3 years ago.
So I'm making a funky VBA class for callback objects. Currently one of the issues is that when returning data from the function's call method I have to run the method twice, one to determine the variable type and another to return the variable:
If VarType(Application.Run(Callback("Parent") & "." & Callback("Name"), args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27), args(28), args(29))) = vbObject Then
Set CallCallback = Application.Run( _
Callback("Parent") & "." & Callback("Name"), _
args(0), args(1), _
args(2), args(3), _
args(4), args(5), _
args(6), args(7), _
args(8), args(9), _
args(10), args(11), _
args(12), args(13), _
args(14), args(15), _
args(16), args(17), _
args(18), args(19), _
args(20), args(21), _
args(22), args(23), _
args(24), args(25), _
args(26), args(27), _
args(28), args(29))
Else
CallCallback = Application.Run( _
Callback("Parent") & "." & Callback("Name"), _
args(0), args(1), _
args(2), args(3), _
args(4), args(5), _
args(6), args(7), _
args(8), args(9), _
args(10), args(11), _
args(12), args(13), _
args(14), args(15), _
args(16), args(17), _
args(18), args(19), _
args(20), args(21), _
args(22), args(23), _
args(24), args(25), _
args(26), args(27), _
args(28), args(29))
End If
Recently I figured that I might be able to do this without calling the VBA function multiple times by dereferencing the result using VarPtr and then using GetMem4:
Private Declare Function GetMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, ByRef RetVal As Any) As Long
...
Dim vp As LongPtr, vRet as Variant
vp = VarPtr(Application.Run(Callback("Parent") & "." & Callback("Name"), args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27), args(28), args(29)))
Call GetMem4(vp, vRet)
This specific example didn't work but I was wondering whether there was an obvious reason as to why this didn't work?
Any ideas?

I asked the question to vbforums also and they got there much faster than stackoverflow!
The solution is extremely simple:
Public Declare Sub VariantCopy Lib "oleaut32.dll" (ByRef pvargDest As Variant, ByRef pvargSrc As Variant)
...
VariantCopy CallCallback, Application.Run( _
Callback("Parent") & "." & Callback("Name"), _
args(0), args(1), _
args(2), args(3), _
args(4), args(5), _
args(6), args(7), _
args(8), args(9), _
args(10), args(11), _
args(12), args(13), _
args(14), args(15), _
args(16), args(17), _
args(18), args(19), _
args(20), args(21), _
args(22), args(23), _
args(24), args(25), _
args(26), args(27), _
args(28), args(29))
Simple!

Related

AttributeError: 'TestCaseFunction' object has no attribute 'wasSuccessful' (UnitTest to Pytest)

I am converting my unittest test cases to pytest.
While running my py file, the script does its function fine (device reboot) but my test script shows the following failure:
================================================================================================ FAILURES =================================================================================================
_________________________________________________________________________________________ TestReboot.test_reboot __________________________________________________________________________________________
../../custom_xmlrunner/custom_unittest_runner.py:245: in run
self.write_result(result)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <device_reboot.TestReboot testMethod=test_reboot>, result = <TestCaseFunction test_reboot>
def write_result(self, result):
"""
Write the result of the test-case, like:
-----------------------
TESTCASE: my_test_case
RESULT: PASS
-----------------------
This too is implicitly called at the end of the test-case.
"""
self.write_log('-' * 60)
self.write_log('TESTCASE: {0}'.format(self._testMethodName))
> if result.wasSuccessful():
E AttributeError: 'TestCaseFunction' object has no attribute 'wasSuccessful'
../../custom_xmlrunner/custom_unittest_runner.py:292: AttributeError

Pytest running unittest failed with Attribute error

I created below function and it's working fine but i am struggling with creating unittest for this function.
Here's my function:
def put_config_file_on_device(device, config_backup=None):
try:
runn_config = config_backup
runn_config_database = running_config_from_database(device)
if runn_config:
raw_config = runn_config
else:
raw_config = runn_config_database
new_file, filename = tempfile.mkstemp()
os.write(new_file, raw_config.encode('utf-8'))
ssh = SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.load_system_host_keys()
handler = get_handler(device)
passwd = handler._get_admin_passwords()[1][0]
ssh.connect(device, username='root', password=get_cred('root'),
look_for_keys=False)
vendor = str(handler)
if 'Juniper' in vendor:
remote_path = f'/var/tmp/{device}.cfg'
if 'Cisco' in vendor:
remote_path = f'harddisk:/{device}.cfg'
scp = SCPClient(ssh.get_transport())
file_path = f'{filename}'
scp.put(file_path, remote_path, recursive=False)
scp.close()
os.remove(filename)
return True, f"File store successfully on the device {remote_path}"
except Exception as err:
return False, f"Failed to store config on Exception: {err}"
I created below unittest but it's not working. I am getting error while tetsinh the UT.
i have mocked all the dependencies but not sure what's wrong with the code. I get Attribute error for <class 'paramiko.client.SSHClient.
#pytest.mark.parametrize('mock_config_backup', ['someconfig\r\n'])
#patch("test.scripts.script.get_cred")
#patch("test.scripts.script.os")
#patch("test.scripts.script.SSHClient.")
#patch("test.scripts.script.SCPClient")
#patch("test.scripts.script.tempfile.mkstemp")
#patch("test.scripts.script.get_device_handler")
def test_put_config_file_on_device(mock_handler, mock_temp, mock_os, mock_ssh, mock_scp, mock_cred, mock_config_backup):
conf = 'someconfig\r\n'
mock_temp.return_value = new_file, filename
mock.os.write(new_file, conf.encode('utf-8'))
remote_path = '/var/tmp/devA.cfg'
file_path = f'{filename}'
mock_cred.return_value = 'xyz'
ret = MagicMock()
ret.connect('devA', username='root', password='xyz', look_for_keys=False)
mock_ssh.return_value = ret
mock_scp.put = (file_path, remote_path)
scp.close()
mock.os.remove(filename)
status, out = test.scripts.script.put_config_file_on_device(device, mock_config_backup)
assert status and out == 'File store successfully on the device /var/tmp/devA.cfg'
getting below error.
=============================================================================================== FAILURES ===============================================================================================
____________________________________________________________________________ test_put_config_file_on_device[someconfig\r\n] ____________________________________________________________________________
args = (), keywargs = {'mock_config_backup': 'someconfig\r\n'}
#wraps(func)
def patched(*args, **keywargs):
with self.decoration_helper(patched,
args,
> keywargs) as (newargs, newkeywargs):
/home/lib/python3.6/site-packages/mock/mock.py:1368:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.6/contextlib.py:81: in __enter__
return next(self.gen)
/home/lib/python3.6/site-packages/mock/mock.py:1334: in decoration_helper
arg = patching.__enter__()
/home/lib/python3.6/site-packages/mock/mock.py:1437: in __enter__
original, local = self.get_original()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <mock.mock._patch object at 0x7f0e60450240>
def get_original(self):
target = self.getter()
name = self.attribute
original = DEFAULT
local = False
try:
original = target.__dict__[name]
except (AttributeError, KeyError):
original = getattr(target, name, DEFAULT)
else:
local = True
if name in _builtins and isinstance(target, ModuleType):
self.create = True
if not self.create and original is DEFAULT:
raise AttributeError(
> "%s does not have the attribute %r" % (target, name)
)
E AttributeError: <class 'paramiko.client.SSHClient'> does not have the attribute ''
/home/lib/python3.6/site-packages/mock/mock.py:1411: AttributeError
===================================================================================== 1 failed, 6 passed in 5.67s

MissingSchema error while test Django via Pytest and Requests

Try to make simple test admin page via python-requests
import requests
from django.urls import reverse
def test_admin():
resp = requests.get(reverse('admin:index'))
assert resp.status_code == 200
but got unexpected error
def test_admin():
> resp = requests.get(reverse('admin:index'))
src/users/tests/test_user_admin.py:6:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv1/lib/python3.5/site-packages/requests/api.py:72: in get
return request('get', url, params=params, **kwargs)
venv1/lib/python3.5/site-packages/requests/api.py:58: in request
return session.request(method=method, url=url, **kwargs)
venv1/lib/python3.5/site-packages/requests/sessions.py:494: in request
prep = self.prepare_request(req)
venv1/lib/python3.5/site-packages/requests/sessions.py:437: in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
venv1/lib/python3.5/site-packages/requests/models.py:305: in prepare
self.prepare_url(url, params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> raise MissingSchema(error)
E requests.exceptions.MissingSchema: Invalid URL '/admin/': No schema supplied. Perhaps you meant http:///admin/?
venv1/lib/python3.5/site-packages/requests/models.py:379: MissingSchema
List of installed packages
pytest==3.3.2
requests==2.18.4
pytest-django==3.1.2
django==1.10.2
Read a lot of docs and manual but can't find solution.
Test with different pytest.ini, manage.py, wsgi.py and settings.py
Simple tests assert 200==200 work properly.
Where is the problem?
Use request.build_absolute_uri():
resp = requests.get(request.build_absolute_uri(reverse('admin:index')))
As the error suggests, requests requires a url with schema (http, https, ftp etc).
The problem is that reverse returns a relative path (eg /admin/index) but requests needs a full url including a schema (eg http://localhost/admin/index).
If you insist on using reverse('admin:index') rather than hardcoding the full url in the test, you will need to prepend http://localhost:<port>/ (or whatever is the correct host in your case) to whatever reverse('admin:index') returns.

pytest argparse test case does not work

I'm using Python 3.4.6.
Here is the factory:
def create_parser():
""" Create argument parser """
# Input configuration parameters
_parser = argparse.ArgumentParser(description='Segments Engine')
# Application only parameters
_parser.add_argument(
'-V', '--version', version='%(prog)s ' + __version__,
action='version')
_pasrser.add_argument(
'-d', '--debug', action='store_true')
return _parser
The test case is as follows:
class TestCli(unittest.TestCase):
""" Test the cli.py module """
def __init__(self, *args, **kwargs):
""" Initialize Unit Test """
super(TestCli, self).__init__(*args, **kwargs)
def setup(self):
""" Setup before each test case """
setup_config(app)
setup_logging(app)
def teardown(self):
""" Tear down after each test case """
pass
def test_version(self):
parser = create_parser()
with pytest.raises(SystemExit):
args = vars(parser.parse_args(['', '-V']))
assert args.version == __version__
def test_debug(self):
parser = create_parser()
args = parser.parse_args(['-d'])
assert args.debug
Then I execute as follows:
pytest tests/test_cli.py
I get the following errors, what am I doing wrong?
======================================================================================= test session starts =========================================================================================
platform darwin -- Python 3.4.6, pytest-3.1.3, py-1.4.34, pluggy-0.4.0
rootdir: /Users/francisco.benavides/Documents/src/segments-engine, inifile:
collected 1 item s
tests/test_cli.py F
self = <tests.test_cli.TestCli testMethod=test_version>
def test_version(self):
parser = create_parser()
> args = vars(parser.parse_args(['', '-V']))
tests/test_cli.py:29:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../.pyenv/versions/3.4.6/lib/python3.4/argparse.py:1728: in parse_args
args, argv = self.parse_known_args(args, namespace)
../../../.pyenv/versions/3.4.6/lib/python3.4/argparse.py:1760: in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
../../../.pyenv/versions/3.4.6/lib/python3.4/argparse.py:1966: in _parse_known_args
start_index = consume_optional(start_index)
../../../.pyenv/versions/3.4.6/lib/python3.4/argparse.py:1906: in consume_optional
take_action(action, args, option_string)
../../../.pyenv/versions/3.4.6/lib/python3.4/argparse.py:1834: in take_action
action(self, namespace, argument_values, option_string)
../../../.pyenv/versions/3.4.6/lib/python3.4/argparse.py:1043: in __call__
parser.exit()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = ArgumentParser(prog='pytest', usage=None, description='Segments Engine', formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True), status = 0, message = None
def exit(self, status=0, message=None):
if message:
self._print_message(message, _sys.stderr)
> _sys.exit(status)
E SystemExit: 0
../../../.pyenv/versions/3.4.6/lib/python3.4/argparse.py:2373: SystemExit
---------------------------------------------------------------------------------------- Captured stdout call ----------------------------------------------------------------------------------------
pytest 0.0.1
I have tried several ways I found googling, but so far nothing has helped me.
Just a guess since you haven't shown us your create_parser implementation:
-V is a "version" type command (?), if you read the docs version is to
"[print] version information and [exit] when invoked".
You'll want to capture the exit, here's one way:
with pytest.raises(SystemExit):
parser.parse_args(['', '-V'])
# maybe use `capsys` to verify that the version was printed
out, err = capsys.readouterr()
# ...

A syntax error when passing a NumPy array to a function created with lambdify in SymPy

I am trying to use pytest on a function which takes as input a string and it parses it with lambdify.
from sympy import sympify, symbols, lambdify
import numpy as np
def func(x):
a = np.arange(10)
expr = 'sin(x)'
f = lambdify(x, sympify(expr), 'numpy')
return f(a)
def test_answer():
thelist = np.array([
0., 0.84147098, 0.90929743, 0.14112001, -0.7568025, -0.95892427,
-0.2794155, 0.6569866, 0.98935825, 0.41211849])
assert func(np.arange(10)) == thelist
if __name__ == "__main__":
x = symbols('x')
func(x)
I am receiving :
assert func(np.arange(10)) == thelist
test_sample.py:23: (it is the `assert func()`)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
test_sample.py:13: in func (it is the `f = lambdify(x, sympify(expr), 'numpy')`)
f = lambdify(x, sympify(expr), 'numpy')
...
func = eval(lstr, namespace)
E File "<string>", line 1
E lambda 0,1,2,3,4,5,6,7,8,9: (sin(x))
E ^
E SyntaxError: invalid syntax
../anaconda2/envs/pytest/lib/python3.6/site-packages/sympy/utilities/lambdify.py:387: SyntaxError
---- UPDATE ----------------
If I use this code:
from sympy import symbols, sin
from sympy.utilities.autowrap import ufuncify
import numpy as np
def func(x):
a = np.arange(10)
f = ufuncify(x, sin(x), backend='numpy')
return f(a)
def test_answer():
thelist = np.array([
0., 0.84147098, 0.90929743, 0.14112001, -0.7568025, -0.95892427,
-0.2794155, 0.6569866, 0.98935825, 0.41211849])
assert all(func(np.arange(10)) == thelist)
if __name__ == "__main__":
x = symbols('x')
func(x)
and run it with pytest, I am getting :
args = (sin, array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])), kwargs = {}
def wrapper(*args, **kwargs):
try:
> retval = cfunc(*args, **kwargs)
E TypeError: unhashable type: 'numpy.ndarray'
../anaconda3/envs/parsing/lib/python3.6/site-packages/sympy/core/cache.py:93: TypeError
During handling of the above exception, another exception occurred:
args = (sin, array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])), kwargs = {}
def wrapper(*args, **kwargs):
try:
> retval = cfunc(*args, **kwargs)
E TypeError: unhashable type: 'numpy.ndarray'
../anaconda3/envs/parsing/lib/python3.6/site-packages/sympy/core/cache.py:93: TypeError
During handling of the above exception, another exception occurred:
def test_answer():
thelist = np.array([
0., 0.84147098, 0.90929743, 0.14112001, -0.7568025, -0.95892427,
-0.2794155, 0.6569866, 0.98935825, 0.41211849])
> assert all(func(np.arange(10)) == thelist)
test_ufuncify.py:23:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
test_ufuncify.py:14: in func
f = ufuncify(x, sin(x), backend='numpy')
../anaconda3/envs/parsing/lib/python3.6/site-packages/sympy/core/cache.py:95: in wrapper
retval = func(*args, **kwargs)
../anaconda3/envs/parsing/lib/python3.6/site-packages/sympy/core/function.py:385: in __new__
result = super(Function, cls).__new__(cls, *args, **options)
../anaconda3/envs/parsing/lib/python3.6/site-packages/sympy/core/cache.py:95: in wrapper
retval = func(*args, **kwargs)
../anaconda3/envs/parsing/lib/python3.6/site-packages/sympy/core/function.py:209: in __new__
evaluated = cls.eval(*args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = sin, arg = array([], shape=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), dtype=float64)
#classmethod
def eval(cls, arg):
from sympy.calculus import AccumBounds
> if arg.is_Number:
E AttributeError: 'numpy.ndarray' object has no attribute 'is_Number'
../anaconda3/envs/parsing/lib/python3.6/site-packages/sympy/functions/elementary/trigonometric.py:228: AttributeError
In order to create a binary function that supports NumPy broadcasting, you need ufuncify, not lambdify. There are other issues with your code:
The assertion statement should be of the form all(array1 == array2)
You use x as a function parameter and also as a SymPy symbol - within the same function.
You have copied low-precision rounded values of sin(1), sin(2), ... which are not equal to the actual output of sine function.
You have not imported the sine function
Here is this code with the issues rectified:
from sympy import symbols, sin
from sympy.utilities.autowrap import ufuncify
import numpy as np
def test_answer():
thelist = np.array([0.0, 0.8414709848078965, 0.90929742682568171, 0.14112000805986721, -0.7568024953079282, -0.95892427466313845, -0.27941549819892586, 0.65698659871878906, 0.98935824662338179, 0.41211848524175659])
assert all(func(np.arange(10)) == thelist)
x = symbols('x')
func = ufuncify(x, sin(x), backend='numpy')
test_answer()
Remark
Use repr(a) to get a string that accurately represents a number a. The values printed with print are rounded. There is also set_printoptions

Resources