Skip to content

Commit

Permalink
Merge branch 'master' into ttdoa-bkex
Browse files Browse the repository at this point in the history
  • Loading branch information
frosty00 committed Mar 12, 2022
2 parents fa982cc + 69c1db9 commit 93e1d12
Show file tree
Hide file tree
Showing 409 changed files with 29,883 additions and 8,750 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ python/keys.json
python/LICENSE.txt
.env
*.swp
.cache
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ python:
- "3.8"
cache:
directories:
# - $HOME/.cache/pip
# - $HOME/.npm
# - node_modules
- .cache

before_install:
- set -e
Expand Down
18 changes: 11 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ The `ccxt.browser.js` is generated with Babel from source.
These files containing derived exchange classes are transpiled from JS into Python:

- `js/[_a-z].js``python/ccxt/async/[_a-z].py`
- `python/ccxt/async[_a-z].py``python/ccxt/[_a-z].py` (Python 3 asyncio → Python 2 sync transpilation stage)
- `python/ccxt/async[_a-z].py``python/ccxt/[_a-z].py` (Python 3 asyncio → Python sync transpilation stage)
- `python/ccxt/test/test_async.py``python/ccxt/test/test_sync.py` (the sync test is generated from the async test)

These Python base classes and files are not transpiled:
Expand Down Expand Up @@ -496,14 +496,18 @@ if (object['key'] || other_value) { /* will not work in Python or PHP! */ }

Therefore we have a family of `safe*` functions:

- `safeInteger (object, key)`, `safeInteger2 (object, key1, key2)`
- `safeFloat (object, key)`, `safeFloat2 (object, key1, key2)`
- `safeString (object, key)`, `safeString2 (object, key1, key2)`
- `safeValue (object, key)`, `safeValue2 (object, key1, key2)`
- `safeInteger (object, key, default)`, `safeInteger2 (object, key1, key2, default)` –for parsing timestamps in milliseconds
- `safeNumber (object, key, default)`, `safeNumber2 (object, key1, key2, default)` – for parsing amounts, prices, costs
- `safeString (object, key, default)`, `safeString2 (object, key1, key2, default)` – for parsing ids, types, statuses
- `safeStringLower (object, key, default)`, `safeStringLower2 (object, key1, key2, default)` – for parsing and turning to lowercase
- `safeStringUpper (object, key, default)`, `safeStringUpper2 (object, key1, key2, default)` – for parsing and turning to lowercase
- `safeValue (object, key, default)`, `safeValue2 (object, key1, key2, default)` – for parsing objects (dictionaries) and arrays (lists)
- `safeTimestamp (object, key, default)`, `safeTimestamp2 (object, key1, key2, default)` – for parsing UNIX timestamps in seconds


The `safeValue` function is used for objects inside objects, arrays inside objects and boolean `true/false` values.

The above safe-functions will check for the existence of the key in the object and will properly return `undefined/None/null` values for JS/Python/PHP. Each function also accepts the default value to be returned instead of `undefined/None/null` in the last argument.
The above safe-functions will check for the existence of the `key` (or `key1`, `key2`) in the object and will properly return `undefined/None/null` values for JS/Python/PHP. Each function also accepts the `default` value to be returned instead of `undefined/None/null` in the last argument.

Alternatively, you could check for the key existence first...

Expand Down Expand Up @@ -983,7 +987,7 @@ node run-tests --js # test master ccxt.js, all exchanges

# other examples require the 'npm run build' to run

node run-tests --python # test Python 2 version, all exchanges
node run-tests --python # test Python sync version, all exchanges
node run-tests --php bitfinex # test Bitfinex with PHP
node run-tests --python-async kraken # test Kraken with Python async test, requires 'npm run build'
```
Expand Down
13 changes: 6 additions & 7 deletions README.md

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ install:
- setx PATH "%PATH%"
- ps: Set-Service wuauserv -StartupType Manual
- cinst -y php --allow-empty-checksums
# - php -i
- cd c:\tools\php81
- copy php.ini-production php.ini
- echo date.timezone="UTC" >> php.ini
Expand All @@ -45,6 +46,10 @@ test_script:
cache:
- '%APPDATA%\npm-cache'
- '%LOCALAPPDATA%\pip\Cache'
# - C:\ProgramData\chocolatey\bin
# - C:\ProgramData\chocolatey\lib
# - C:\tools\php81
- .cache
after_build:
# Remove old or huge cache files to hopefully not exceed the 1GB cache limit.
#
Expand Down
33 changes: 10 additions & 23 deletions build/transpile.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,10 @@ class Transpiler {
// [ /([^\s]+)\s+\=\=\=?\s+false/g, 'isinstance($1, bool) and ($1 is False)' ],
// [ /([^\s]+)\s+\!\=\=?\s+false/g, 'isinstance($1, bool) and ($1 is not False)' ],

[ /typeof\s+([^\s\[]+)(?:\s|\[(.+?)\])\s+\=\=\=?\s+\'string\'/g, 'isinstance($1[$2], basestring)' ],
[ /typeof\s+([^\s\[]+)(?:\s|\[(.+?)\])\s+\!\=\=?\s+\'string\'/g, 'not isinstance($1[$2], basestring)' ],
[ /typeof\s+([^\s]+)\s+\=\=\=?\s+\'string\'/g, 'isinstance($1, basestring)' ],
[ /typeof\s+([^\s]+)\s+\!\=\=?\s+\'string\'/g, 'not isinstance($1, basestring)' ],
[ /typeof\s+([^\s\[]+)(?:\s|\[(.+?)\])\s+\=\=\=?\s+\'string\'/g, 'isinstance($1[$2], str)' ],
[ /typeof\s+([^\s\[]+)(?:\s|\[(.+?)\])\s+\!\=\=?\s+\'string\'/g, 'not isinstance($1[$2], str)' ],
[ /typeof\s+([^\s]+)\s+\=\=\=?\s+\'string\'/g, 'isinstance($1, str)' ],
[ /typeof\s+([^\s]+)\s+\!\=\=?\s+\'string\'/g, 'not isinstance($1, str)' ],

[ /typeof\s+([^\s\[]+)(?:\s|\[(.+?)\])\s+\=\=\=?\s+\'object\'/g, 'isinstance($1[$2], dict)' ],
[ /typeof\s+([^\s\[]+)(?:\s|\[(.+?)\])\s+\!\=\=?\s+\'object\'/g, 'not isinstance($1[$2], dict)' ],
Expand All @@ -233,6 +233,7 @@ class Transpiler {
[ /Precise\.stringNeg\s/g, 'Precise.string_neg' ],
[ /Precise\.stringMod\s/g, 'Precise.string_mod' ],
[ /Precise\.stringEquals\s/g, 'Precise.string_equals' ],
[ /Precise\.stringEq\s/g, 'Precise.string_eq' ],
[ /Precise\.stringMin\s/g, 'Precise.string_min' ],
[ /Precise\.stringMax\s/g, 'Precise.string_max' ],
[ /Precise\.stringGt\s/g, 'Precise.string_gt' ],
Expand Down Expand Up @@ -575,16 +576,6 @@ class Transpiler {
"# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code",
"",
... imports,
// 'from ' + importFrom + ' import ' + baseClass,
... (bodyAsString.match (/basestring/) ? [
"",
"# -----------------------------------------------------------------------------",
"",
"try:",
" basestring # Python 3",
"except NameError:",
" basestring = str # Python 2",
] : [])
]
}

Expand Down Expand Up @@ -822,7 +813,7 @@ class Transpiler {

transpilePython3ToPython2 (py) {

// remove await from Python 2 body (transpile Python 3 → Python 2)
// remove await from Python sync body (transpile Python async → Python sync)
let python2Body = this.regexAll (py, this.getPython2Regexes ())

return python2Body
Expand Down Expand Up @@ -899,7 +890,7 @@ class Transpiler {
// transpile JS → Python 3
let python3Body = this.transpileJavaScriptToPython3 (args)

// remove await from Python 2 body (transpile Python 3 → Python 2)
// remove await from Python sync body (transpile Python async → Python sync)
let python2Body = this.transpilePython3ToPython2 (python3Body)

// transpile JS → Async PHP
Expand Down Expand Up @@ -1051,12 +1042,12 @@ class Transpiler {
// compile the final Python code for the method signature
let pythonString = 'def ' + method + '(self' + (pythonArgs.length ? ', ' + pythonArgs : '') + '):'

// compile signature + body for Python 2
// compile signature + body for Python sync
python2.push ('');
python2.push (' ' + pythonString);
python2.push (python2Body);

// compile signature + body for Python 3
// compile signature + body for Python async
python3.push ('');
python3.push (' ' + keyword + pythonString);
python3.push (python3Body);
Expand All @@ -1075,7 +1066,7 @@ class Transpiler {

return {

// altogether in PHP, async PHP, Python 2 and 3 (async)
// altogether in PHP, async PHP, Python sync and async
python2: this.createPythonClass (className, baseClass, python2, methodNames),
python3: this.createPythonClass (className, baseClass, python3, methodNames, true),
php: this.createPHPClass (className, baseClass, php, methodNames),
Expand Down Expand Up @@ -1601,10 +1592,6 @@ class Transpiler {

const pythonHeader = [
'import numbers # noqa: E402',
'try:',
' basestring # basestring was removed in Python 3',
'except NameError:',
' basestring = str',
'',
'',
].join('\n')
Expand Down
2 changes: 1 addition & 1 deletion ccxt.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const Exchange = require ('./js/base/Exchange')
//-----------------------------------------------------------------------------
// this is updated by vss.js when building

const version = '1.74.49'
const version = '1.75.92'

Exchange.ccxtVersion = version

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@
"suggest": {
"recoil/recoil": "Required for asynchronous API calls to exchanges with PHP",
"recoil/react": "Required for asynchronous API calls to exchanges with PHP",
"react/http": "Required for asynchronous API calls to exchanges with PHP",
"clue/buzz-react": "Required for asynchronous API calls to exchanges with PHP",
"react/event-loop": "Required for asynchronous API calls to exchanges with PHP",
"clue/http-proxy-react": "Required for using a proxy when doing asynchronous API calls to exchanges with PHP"
Expand Down
Loading

0 comments on commit 93e1d12

Please sign in to comment.