Skip to content

Commit

Permalink
fix #132 #129
Browse files Browse the repository at this point in the history
  • Loading branch information
bsrdjan committed Oct 31, 2019
1 parent cb84da4 commit b2d273a
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 133 deletions.
11 changes: 9 additions & 2 deletions CHANGES
@@ -1,10 +1,17 @@
Change log
==========

1.9.99 (2012-10-25)
2.0.0 (2019-11-01)
------------------

- Documentation
- macOS rpath fix/show scripts
- Tables and structure parameters type check

1.9.99 (2019-10-25)
-------------------

- Python 3.8 wheels added, 3.6 and 3.5 dropped
- Python 3.8 wheels added, 3,6, 3.5 dropped
- Datatypes checks and unit test, fix #91, #120
- Connection info request when disconnected, does not open the connection any more
- Connection and RFM call parameters check
Expand Down
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
1.9.99
2.0.0
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions setup.py
Expand Up @@ -32,7 +32,7 @@ def _read(name):


if sys.platform.startswith("linux"):
subprocess.call("./tests/nwrfcsdk-version-linux.sh", shell=True)
subprocess.call("./ci/utils/nwrfcsdk-version-linux.sh", shell=True)
LIBS = ["sapnwrfc", "sapucum"]
MACROS = [
("NDEBUG", None),
Expand All @@ -59,7 +59,7 @@ def _read(name):
]
LINK_ARGS = ["-L{}/lib".format(SAPNWRFC_HOME)]
elif sys.platform.startswith("win"):
subprocess.call("tests\\nwrfcsdk-version.bat", shell=True)
subprocess.call("ci\\utils\\nwrfcsdk-version.bat", shell=True)
LIBS = ["sapnwrfc", "libsapucum"]
MACROS = [
("_LARGEFILE_SOURCE", None),
Expand All @@ -81,7 +81,7 @@ def _read(name):
"-LIBPATH:{}\\PCbuild".format(PYTHONSOURCE),
]
elif sys.platform.startswith("darwin"):
subprocess.call("./tests/nwrfcsdk-version-darwin.sh", shell=True)
subprocess.call("./ci/utils/nwrfcsdk-version-darwin.sh", shell=True)
MACOS_VERSION_MIN = "10.10"
# unicode paths fix
# https://apple.stackexchange.com/questions/337940/why-is-usr-include-missing-i-have-xcode-and-command-line-tools-installed-moja
Expand Down
5 changes: 3 additions & 2 deletions src/pyrfc/__init__.py
Expand Up @@ -18,7 +18,8 @@

# Set DLL path, due to https://docs.python.org/3.8/whatsnew/3.8.html#bpo-36085-whatsnew
import os
if os.name == 'nt':

if os.name == "nt":
try:
os.add_dll_directory(os.path.join(os.environ["SAPNWRFC_HOME"], "lib"))
except Exception:
Expand Down Expand Up @@ -46,4 +47,4 @@

__author__ = """"Srdjan Boskovic"""
__email__ = "srdjan.boskovic@sap.com"
__version__ = "1.9.99"
__version__ = "2.0.0"
78 changes: 48 additions & 30 deletions src/pyrfc/_pyrfc.pyx
Expand Up @@ -387,7 +387,8 @@ cdef class Connection:
cdef unsigned paramCount
cdef SAP_UC *cName
if type(func_name) is not str:
raise RFCError("Remote function module name must be a string, received:", func_name)
if type(func_name) is not unicode:
raise RFCError("Remote function module name must be unicode string, received:", func_name, type(func_name))
cdef SAP_UC *funcName = fillString(func_name)
if not self.alive:
self._open()
Expand Down Expand Up @@ -1686,14 +1687,19 @@ cdef fillVariable(RFCTYPE typ, RFC_FUNCTION_HANDLE container, SAP_UC* cName, val
cdef RFC_TABLE_HANDLE table
cdef SAP_UC* cValue
cdef SAP_RAW* bValue
#print ("fill", wrapString(cName), value)
try:
if typ == RFCTYPE_STRUCTURE:
if type(value) is not dict:
raise TypeError('dictionary required for structure parameter, received', str(type(value)))
rc = RfcGetStructure(container, cName, &struct, &errorInfo)
if rc != RFC_OK:
raise wrapError(&errorInfo)
for name, value in value.iteritems():
fillStructureField(typeDesc, struct, name, value)
elif typ == RFCTYPE_TABLE:
if type(value) is not list:
raise TypeError('list required for table parameter, received', str(type(value)))
rc = RfcGetTable(container, cName, &table, &errorInfo)
if rc != RFC_OK:
raise wrapError(&errorInfo)
Expand All @@ -1708,21 +1714,21 @@ cdef fillVariable(RFCTYPE typ, RFC_FUNCTION_HANDLE container, SAP_UC* cName, val
free(bValue)
elif typ == RFCTYPE_CHAR:
if type(value) is not str and type(value) is not unicode:
raise TypeError('an string is required, received', value, 'of type:', str(type(value)))
raise TypeError('an string is required, received', value, 'of type', str(type(value)))
cValue = fillString(value)
rc = RfcSetChars(container, cName, cValue, strlenU(cValue), &errorInfo)
free(cValue)
elif typ == RFCTYPE_STRING:
if type(value) is not str and type(value) is not unicode:
raise TypeError('an string is required, received', value, 'of type:', str(type(value)))
raise TypeError('an string is required, received', value, 'of type', str(type(value)))
cValue = fillString(value)
rc = RfcSetString(container, cName, cValue, strlenU(cValue), &errorInfo)
free(cValue)
elif typ == RFCTYPE_NUM:
try:
Decimal(value)
except:
raise TypeError('a decimal value is required, received', value)
raise TypeError('a decimal value is required, received', value, 'of type', str(type(value)))
cValue = fillString(value)
rc = RfcSetNum(container, cName, cValue, strlenU(cValue), &errorInfo)
free(cValue)
Expand All @@ -1731,49 +1737,61 @@ cdef fillVariable(RFCTYPE typ, RFC_FUNCTION_HANDLE container, SAP_UC* cName, val
try:
Decimal(value)
except:
raise TypeError('a decimal value is required, received', value)
raise TypeError('a decimal value required, received', value, 'of type', str(type(value)))
cValue = fillString(str(value))
rc = RfcSetString(container, cName, cValue, strlenU(cValue), &errorInfo)
free(cValue)
elif typ in (RFCTYPE_INT, RFCTYPE_INT1, RFCTYPE_INT2):
if type(value) is not int:
raise TypeError('an integer is required, received', value)
raise TypeError('an integer required, received', value, 'of type', str(type(value)))
rc = RfcSetInt(container, cName, value, &errorInfo)
elif typ == RFCTYPE_INT8:
if type(value) is not int:
raise TypeError('an integer is required, received', value)
raise TypeError('an integer required, received', value, 'of type', str(type(value)))
rc = RfcSetInt8(container, cName, value, &errorInfo)
elif typ == RFCTYPE_DATE:
if (value): # not None or empty
try:
if type(value) is datetime.date:
cValue = fillString('{:04d}{:02d}{:02d}'.format(value.year, value.month, value.day))
else:
# raise len error
if len(value) != 8: raise
# raise type or out of range error
datetime.date(int(value[:4]), int(value[4:6]), int(value[6:8]))
cValue = fillString(value)
except:
raise TypeError('a date value required, received', value)
format_ok = True
if type(value) is datetime.date:
cValue = fillString('{:04d}{:02d}{:02d}'.format(value.year, value.month, value.day))
else:
try:
if len(value) != 8:
format_ok = False
else:
if len(value.rstrip()) > 0:
datetime.date(int(value[:4]), int(value[4:6]), int(value[6:8]))
cValue = fillString(value)
except:
format_ok = False
if not format_ok:
raise TypeError('date value required, received', value, 'of type', str(type(value)))
rc = RfcSetDate(container, cName, cValue, &errorInfo)
free(cValue)
else:
rc = RFC_OK
elif typ == RFCTYPE_TIME:
if (value): # not None or empty
try:
if type(value) is datetime.time:
cValue = fillString('{:02d}{:02d}{:02d}'.format(value.hour, value.minute, value.second))
else:
# raise len error
if len(value) != 6: raise
# raise type or out of range error
datetime.time(int(value[:2]), int(value[2:4]), int(value[4:6]))
cValue = fillString(value)
except:
#raise RFCError('Invalid time value when filling %s: %s' % (wrapString(cName), str(value)))
raise TypeError('a time value required, received', value)
format_ok = True
if type(value) is datetime.time:
cValue = fillString('{:02d}{:02d}{:02d}'.format(value.hour, value.minute, value.second))
else:
try:
if len(value) != 6:
format_ok = False
else:
if len(value.rstrip()) > 0:
datetime.time(int(value[:2]), int(value[2:4]), int(value[4:6]))
cValue = fillString(value)
except:
format_ok = False

if not format_ok:
raise TypeError('time value required, received', value, 'of type', str(type(value)))
rc = RfcSetTime(container, cName, cValue, &errorInfo)
free(cValue)
else:
rc = RFC_OK
else:
raise RFCError('Unknown RFC type %d when filling %s' % (typ, wrapString(cName)))
except TypeError as e:
Expand Down
16 changes: 15 additions & 1 deletion tests/test_connection.py
Expand Up @@ -134,10 +134,24 @@ def test_ping(self):
assert error["key"] == "RFC_INVALID_HANDLE"
assert error["message"][0] == "An invalid handle was passed to the API call"

def test_STFC_returns_unicode(self):
def test_RFM_name_string(self):
result = self.conn.call("STFC_CONNECTION", REQUTEXT=UNICODETEST)
assert result["ECHOTEXT"] == UNICODETEST

def test_RFM_name_unicode(self):
result = self.conn.call(u"STFC_CONNECTION", REQUTEXT=UNICODETEST)
assert result["ECHOTEXT"] == UNICODETEST

def test_RFM_name_invalid_type(self):
try:
self.conn.call(123)
except Exception as ex:
assert ex.args == (
"Remote function module name must be unicode string, received:",
123,
int,
)

def test_STFC_returns_structure_and_table(self):
IMPORTSTRUCT = {
"RFCFLOAT": 1.23456789,
Expand Down

0 comments on commit b2d273a

Please sign in to comment.