Merge pull request #1751 from RustPython/master

Merge to release again to fix demo performance issues
This commit is contained in:
Noah
2020-02-06 11:48:51 -06:00
committed by GitHub
117 changed files with 2663 additions and 1497 deletions

View File

@@ -124,6 +124,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Cache cargo dependencies
uses: actions/cache@v1
with:
key: ${{ runner.os }}-wasm-${{ hashFiles('**/Cargo.lock') }}
path: target
restore-keys: |
${{ runner.os }}-wasm-
- name: install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: install geckodriver

11
Cargo.lock generated
View File

@@ -1245,15 +1245,6 @@ dependencies = [
"getrandom",
]
[[package]]
name = "rand_distr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
dependencies = [
"rand 0.7.3",
]
[[package]]
name = "rand_hc"
version = "0.1.0"
@@ -1539,7 +1530,7 @@ dependencies = [
"paste",
"pwd",
"rand 0.7.3",
"rand_distr",
"rand_core 0.5.1",
"regex",
"result-like",
"rustc_version_runtime",

772
Lib/random.py vendored Normal file
View File

@@ -0,0 +1,772 @@
"""Random variable generators.
integers
--------
uniform within range
sequences
---------
pick random element
pick random sample
pick weighted random sample
generate random permutation
distributions on the real line:
------------------------------
uniform
triangular
normal (Gaussian)
lognormal
negative exponential
gamma
beta
pareto
Weibull
distributions on the circle (angles 0 to 2pi)
---------------------------------------------
circular uniform
von Mises
General notes on the underlying Mersenne Twister core generator:
* The period is 2**19937-1.
* It is one of the most extensively tested generators in existence.
* The random() method is implemented in C, executes in a single Python step,
and is, therefore, threadsafe.
"""
from warnings import warn as _warn
from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
from os import urandom as _urandom
from _collections_abc import Set as _Set, Sequence as _Sequence
from hashlib import sha512 as _sha512
import itertools as _itertools
import bisect as _bisect
__all__ = ["Random","seed","random","uniform","randint","choice","sample",
"randrange","shuffle","normalvariate","lognormvariate",
"expovariate","vonmisesvariate","gammavariate","triangular",
"gauss","betavariate","paretovariate","weibullvariate",
"getstate","setstate", "getrandbits", "choices",
"SystemRandom"]
NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
TWOPI = 2.0*_pi
LOG4 = _log(4.0)
SG_MAGICCONST = 1.0 + _log(4.5)
BPF = 53 # Number of bits in a float
RECIP_BPF = 2**-BPF
# Translated by Guido van Rossum from C source provided by
# Adrian Baddeley. Adapted by Raymond Hettinger for use with
# the Mersenne Twister and os.urandom() core generators.
import _random
class Random(_random.Random):
"""Random number generator base class used by bound module functions.
Used to instantiate instances of Random to get generators that don't
share state.
Class Random can also be subclassed if you want to use a different basic
generator of your own devising: in that case, override the following
methods: random(), seed(), getstate(), and setstate().
Optionally, implement a getrandbits() method so that randrange()
can cover arbitrarily large ranges.
"""
VERSION = 3 # used by getstate/setstate
def __init__(self, x=None):
"""Initialize an instance.
Optional argument x controls seeding, as for Random.seed().
"""
self.seed(x)
self.gauss_next = None
def seed(self, a=None, version=2):
"""Initialize internal state from hashable object.
None or no argument seeds from current time or from an operating
system specific randomness source if available.
If *a* is an int, all bits are used.
For version 2 (the default), all of the bits are used if *a* is a str,
bytes, or bytearray. For version 1 (provided for reproducing random
sequences from older versions of Python), the algorithm for str and
bytes generates a narrower range of seeds.
"""
if version == 1 and isinstance(a, (str, bytes)):
a = a.decode('latin-1') if isinstance(a, bytes) else a
x = ord(a[0]) << 7 if a else 0
for c in map(ord, a):
x = ((1000003 * x) ^ c) & 0xFFFFFFFFFFFFFFFF
x ^= len(a)
a = -2 if x == -1 else x
if version == 2 and isinstance(a, (str, bytes, bytearray)):
if isinstance(a, str):
a = a.encode()
a += _sha512(a).digest()
a = int.from_bytes(a, 'big')
super().seed(a)
self.gauss_next = None
def getstate(self):
"""Return internal state; can be passed to setstate() later."""
return self.VERSION, super().getstate(), self.gauss_next
def setstate(self, state):
"""Restore internal state from object returned by getstate()."""
version = state[0]
if version == 3:
version, internalstate, self.gauss_next = state
super().setstate(internalstate)
elif version == 2:
version, internalstate, self.gauss_next = state
# In version 2, the state was saved as signed ints, which causes
# inconsistencies between 32/64-bit systems. The state is
# really unsigned 32-bit ints, so we convert negative ints from
# version 2 to positive longs for version 3.
try:
internalstate = tuple(x % (2**32) for x in internalstate)
except ValueError as e:
raise TypeError from e
super().setstate(internalstate)
else:
raise ValueError("state with version %s passed to "
"Random.setstate() of version %s" %
(version, self.VERSION))
## ---- Methods below this point do not need to be overridden when
## ---- subclassing for the purpose of using a different core generator.
## -------------------- pickle support -------------------
# Issue 17489: Since __reduce__ was defined to fix #759889 this is no
# longer called; we leave it here because it has been here since random was
# rewritten back in 2001 and why risk breaking something.
def __getstate__(self): # for pickle
return self.getstate()
def __setstate__(self, state): # for pickle
self.setstate(state)
def __reduce__(self):
return self.__class__, (), self.getstate()
## -------------------- integer methods -------------------
def randrange(self, start, stop=None, step=1, _int=int):
"""Choose a random item from range(start, stop[, step]).
This fixes the problem with randint() which includes the
endpoint; in Python this is usually not what you want.
"""
# This code is a bit messy to make it fast for the
# common case while still doing adequate error checking.
istart = _int(start)
if istart != start:
raise ValueError("non-integer arg 1 for randrange()")
if stop is None:
if istart > 0:
return self._randbelow(istart)
raise ValueError("empty range for randrange()")
# stop argument supplied.
istop = _int(stop)
if istop != stop:
raise ValueError("non-integer stop for randrange()")
width = istop - istart
if step == 1 and width > 0:
return istart + self._randbelow(width)
if step == 1:
raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
# Non-unit step argument supplied.
istep = _int(step)
if istep != step:
raise ValueError("non-integer step for randrange()")
if istep > 0:
n = (width + istep - 1) // istep
elif istep < 0:
n = (width + istep + 1) // istep
else:
raise ValueError("zero step for randrange()")
if n <= 0:
raise ValueError("empty range for randrange()")
return istart + istep*self._randbelow(n)
def randint(self, a, b):
"""Return random integer in range [a, b], including both end points.
"""
return self.randrange(a, b+1)
def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type,
Method=_MethodType, BuiltinMethod=_BuiltinMethodType):
"Return a random int in the range [0,n). Raises ValueError if n==0."
random = self.random
getrandbits = self.getrandbits
# Only call self.getrandbits if the original random() builtin method
# has not been overridden or if a new getrandbits() was supplied.
if type(random) is BuiltinMethod or type(getrandbits) is Method:
k = n.bit_length() # don't use (n-1) here because n can be 1
r = getrandbits(k) # 0 <= r < 2**k
while r >= n:
r = getrandbits(k)
return r
# There's an overridden random() method but no new getrandbits() method,
# so we can only use random() from here.
if n >= maxsize:
_warn("Underlying random() generator does not supply \n"
"enough bits to choose from a population range this large.\n"
"To remove the range limitation, add a getrandbits() method.")
return int(random() * n)
if n == 0:
raise ValueError("Boundary cannot be zero")
rem = maxsize % n
limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0
r = random()
while r >= limit:
r = random()
return int(r*maxsize) % n
## -------------------- sequence methods -------------------
def choice(self, seq):
"""Choose a random element from a non-empty sequence."""
try:
i = self._randbelow(len(seq))
except ValueError:
raise IndexError('Cannot choose from an empty sequence') from None
return seq[i]
def shuffle(self, x, random=None):
"""Shuffle list x in place, and return None.
Optional argument random is a 0-argument function returning a
random float in [0.0, 1.0); if it is the default None, the
standard random.random will be used.
"""
if random is None:
randbelow = self._randbelow
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = randbelow(i+1)
x[i], x[j] = x[j], x[i]
else:
_int = int
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = _int(random() * (i+1))
x[i], x[j] = x[j], x[i]
def sample(self, population, k):
"""Chooses k unique random elements from a population sequence or set.
Returns a new list containing elements from the population while
leaving the original population unchanged. The resulting list is
in selection order so that all sub-slices will also be valid random
samples. This allows raffle winners (the sample) to be partitioned
into grand prize and second place winners (the subslices).
Members of the population need not be hashable or unique. If the
population contains repeats, then each occurrence is a possible
selection in the sample.
To choose a sample in a range of integers, use range as an argument.
This is especially fast and space efficient for sampling from a
large population: sample(range(10000000), 60)
"""
# Sampling without replacement entails tracking either potential
# selections (the pool) in a list or previous selections in a set.
# When the number of selections is small compared to the
# population, then tracking selections is efficient, requiring
# only a small set and an occasional reselection. For
# a larger number of selections, the pool tracking method is
# preferred since the list takes less space than the
# set and it doesn't suffer from frequent reselections.
if isinstance(population, _Set):
population = tuple(population)
if not isinstance(population, _Sequence):
raise TypeError("Population must be a sequence or set. For dicts, use list(d).")
randbelow = self._randbelow
n = len(population)
if not 0 <= k <= n:
raise ValueError("Sample larger than population or is negative")
result = [None] * k
setsize = 21 # size of a small set minus size of an empty list
if k > 5:
setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
if n <= setsize:
# An n-length list is smaller than a k-length set
pool = list(population)
for i in range(k): # invariant: non-selected at [0,n-i)
j = randbelow(n-i)
result[i] = pool[j]
pool[j] = pool[n-i-1] # move non-selected item into vacancy
else:
selected = set()
selected_add = selected.add
for i in range(k):
j = randbelow(n)
while j in selected:
j = randbelow(n)
selected_add(j)
result[i] = population[j]
return result
def choices(self, population, weights=None, *, cum_weights=None, k=1):
"""Return a k sized list of population elements chosen with replacement.
If the relative weights or cumulative weights are not specified,
the selections are made with equal probability.
"""
random = self.random
if cum_weights is None:
if weights is None:
_int = int
total = len(population)
return [population[_int(random() * total)] for i in range(k)]
cum_weights = list(_itertools.accumulate(weights))
elif weights is not None:
raise TypeError('Cannot specify both weights and cumulative weights')
if len(cum_weights) != len(population):
raise ValueError('The number of weights does not match the population')
bisect = _bisect.bisect
total = cum_weights[-1]
hi = len(cum_weights) - 1
return [population[bisect(cum_weights, random() * total, 0, hi)]
for i in range(k)]
## -------------------- real-valued distributions -------------------
## -------------------- uniform distribution -------------------
def uniform(self, a, b):
"Get a random number in the range [a, b) or [a, b] depending on rounding."
return a + (b-a) * self.random()
## -------------------- triangular --------------------
def triangular(self, low=0.0, high=1.0, mode=None):
"""Triangular distribution.
Continuous distribution bounded by given lower and upper limits,
and having a given mode value in-between.
http://en.wikipedia.org/wiki/Triangular_distribution
"""
u = self.random()
try:
c = 0.5 if mode is None else (mode - low) / (high - low)
except ZeroDivisionError:
return low
if u > c:
u = 1.0 - u
c = 1.0 - c
low, high = high, low
return low + (high - low) * (u * c) ** 0.5
## -------------------- normal distribution --------------------
def normalvariate(self, mu, sigma):
"""Normal distribution.
mu is the mean, and sigma is the standard deviation.
"""
# mu = mean, sigma = standard deviation
# Uses Kinderman and Monahan method. Reference: Kinderman,
# A.J. and Monahan, J.F., "Computer generation of random
# variables using the ratio of uniform deviates", ACM Trans
# Math Software, 3, (1977), pp257-260.
random = self.random
while 1:
u1 = random()
u2 = 1.0 - random()
z = NV_MAGICCONST*(u1-0.5)/u2
zz = z*z/4.0
if zz <= -_log(u2):
break
return mu + z*sigma
## -------------------- lognormal distribution --------------------
def lognormvariate(self, mu, sigma):
"""Log normal distribution.
If you take the natural logarithm of this distribution, you'll get a
normal distribution with mean mu and standard deviation sigma.
mu can have any value, and sigma must be greater than zero.
"""
return _exp(self.normalvariate(mu, sigma))
## -------------------- exponential distribution --------------------
def expovariate(self, lambd):
"""Exponential distribution.
lambd is 1.0 divided by the desired mean. It should be
nonzero. (The parameter would be called "lambda", but that is
a reserved word in Python.) Returned values range from 0 to
positive infinity if lambd is positive, and from negative
infinity to 0 if lambd is negative.
"""
# lambd: rate lambd = 1/mean
# ('lambda' is a Python reserved word)
# we use 1-random() instead of random() to preclude the
# possibility of taking the log of zero.
return -_log(1.0 - self.random())/lambd
## -------------------- von Mises distribution --------------------
def vonmisesvariate(self, mu, kappa):
"""Circular data distribution.
mu is the mean angle, expressed in radians between 0 and 2*pi, and
kappa is the concentration parameter, which must be greater than or
equal to zero. If kappa is equal to zero, this distribution reduces
to a uniform random angle over the range 0 to 2*pi.
"""
# mu: mean angle (in radians between 0 and 2*pi)
# kappa: concentration parameter kappa (>= 0)
# if kappa = 0 generate uniform random angle
# Based upon an algorithm published in: Fisher, N.I.,
# "Statistical Analysis of Circular Data", Cambridge
# University Press, 1993.
# Thanks to Magnus Kessler for a correction to the
# implementation of step 4.
random = self.random
if kappa <= 1e-6:
return TWOPI * random()
s = 0.5 / kappa
r = s + _sqrt(1.0 + s * s)
while 1:
u1 = random()
z = _cos(_pi * u1)
d = z / (r + z)
u2 = random()
if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):
break
q = 1.0 / r
f = (q + z) / (1.0 + q * z)
u3 = random()
if u3 > 0.5:
theta = (mu + _acos(f)) % TWOPI
else:
theta = (mu - _acos(f)) % TWOPI
return theta
## -------------------- gamma distribution --------------------
def gammavariate(self, alpha, beta):
"""Gamma distribution. Not the gamma function!
Conditions on the parameters are alpha > 0 and beta > 0.
The probability distribution function is:
x ** (alpha - 1) * math.exp(-x / beta)
pdf(x) = --------------------------------------
math.gamma(alpha) * beta ** alpha
"""
# alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
# Warning: a few older sources define the gamma distribution in terms
# of alpha > -1.0
if alpha <= 0.0 or beta <= 0.0:
raise ValueError('gammavariate: alpha and beta must be > 0.0')
random = self.random
if alpha > 1.0:
# Uses R.C.H. Cheng, "The generation of Gamma
# variables with non-integral shape parameters",
# Applied Statistics, (1977), 26, No. 1, p71-74
ainv = _sqrt(2.0 * alpha - 1.0)
bbb = alpha - LOG4
ccc = alpha + ainv
while 1:
u1 = random()
if not 1e-7 < u1 < .9999999:
continue
u2 = 1.0 - random()
v = _log(u1/(1.0-u1))/ainv
x = alpha*_exp(v)
z = u1*u1*u2
r = bbb+ccc*v-x
if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
return x * beta
elif alpha == 1.0:
# expovariate(1)
u = random()
while u <= 1e-7:
u = random()
return -_log(u) * beta
else: # alpha is between 0 and 1 (exclusive)
# Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
while 1:
u = random()
b = (_e + alpha)/_e
p = b*u
if p <= 1.0:
x = p ** (1.0/alpha)
else:
x = -_log((b-p)/alpha)
u1 = random()
if p > 1.0:
if u1 <= x ** (alpha - 1.0):
break
elif u1 <= _exp(-x):
break
return x * beta
## -------------------- Gauss (faster alternative) --------------------
def gauss(self, mu, sigma):
"""Gaussian distribution.
mu is the mean, and sigma is the standard deviation. This is
slightly faster than the normalvariate() function.
Not thread-safe without a lock around calls.
"""
# When x and y are two variables from [0, 1), uniformly
# distributed, then
#
# cos(2*pi*x)*sqrt(-2*log(1-y))
# sin(2*pi*x)*sqrt(-2*log(1-y))
#
# are two *independent* variables with normal distribution
# (mu = 0, sigma = 1).
# (Lambert Meertens)
# (corrected version; bug discovered by Mike Miller, fixed by LM)
# Multithreading note: When two threads call this function
# simultaneously, it is possible that they will receive the
# same return value. The window is very small though. To
# avoid this, you have to use a lock around all calls. (I
# didn't want to slow this down in the serial case by using a
# lock here.)
random = self.random
z = self.gauss_next
self.gauss_next = None
if z is None:
x2pi = random() * TWOPI
g2rad = _sqrt(-2.0 * _log(1.0 - random()))
z = _cos(x2pi) * g2rad
self.gauss_next = _sin(x2pi) * g2rad
return mu + z*sigma
## -------------------- beta --------------------
## See
## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
## for Ivan Frohne's insightful analysis of why the original implementation:
##
## def betavariate(self, alpha, beta):
## # Discrete Event Simulation in C, pp 87-88.
##
## y = self.expovariate(alpha)
## z = self.expovariate(1.0/beta)
## return z/(y+z)
##
## was dead wrong, and how it probably got that way.
def betavariate(self, alpha, beta):
"""Beta distribution.
Conditions on the parameters are alpha > 0 and beta > 0.
Returned values range between 0 and 1.
"""
# This version due to Janne Sinkkonen, and matches all the std
# texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
y = self.gammavariate(alpha, 1.0)
if y == 0:
return 0.0
else:
return y / (y + self.gammavariate(beta, 1.0))
## -------------------- Pareto --------------------
def paretovariate(self, alpha):
"""Pareto distribution. alpha is the shape parameter."""
# Jain, pg. 495
u = 1.0 - self.random()
return 1.0 / u ** (1.0/alpha)
## -------------------- Weibull --------------------
def weibullvariate(self, alpha, beta):
"""Weibull distribution.
alpha is the scale parameter and beta is the shape parameter.
"""
# Jain, pg. 499; bug fix courtesy Bill Arms
u = 1.0 - self.random()
return alpha * (-_log(u)) ** (1.0/beta)
## --------------- Operating System Random Source ------------------
class SystemRandom(Random):
"""Alternate random number generator using sources provided
by the operating system (such as /dev/urandom on Unix or
CryptGenRandom on Windows).
Not available on all systems (see os.urandom() for details).
"""
def random(self):
"""Get the next random number in the range [0.0, 1.0)."""
return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF
def getrandbits(self, k):
"""getrandbits(k) -> x. Generates an int with k random bits."""
if k <= 0:
raise ValueError('number of bits must be greater than zero')
if k != int(k):
raise TypeError('number of bits should be an integer')
numbytes = (k + 7) // 8 # bits / 8 and rounded up
x = int.from_bytes(_urandom(numbytes), 'big')
return x >> (numbytes * 8 - k) # trim excess bits
def seed(self, *args, **kwds):
"Stub method. Not used for a system random number generator."
return None
def _notimplemented(self, *args, **kwds):
"Method should not be called for a system random number generator."
raise NotImplementedError('System entropy source does not have state.')
getstate = setstate = _notimplemented
## -------------------- test program --------------------
def _test_generator(n, func, args):
import time
print(n, 'times', func.__name__)
total = 0.0
sqsum = 0.0
smallest = 1e10
largest = -1e10
t0 = time.time()
for i in range(n):
x = func(*args)
total += x
sqsum = sqsum + x*x
smallest = min(x, smallest)
largest = max(x, largest)
t1 = time.time()
print(round(t1-t0, 3), 'sec,', end=' ')
avg = total/n
stddev = _sqrt(sqsum/n - avg*avg)
print('avg %g, stddev %g, min %g, max %g\n' % \
(avg, stddev, smallest, largest))
def _test(N=2000):
_test_generator(N, random, ())
_test_generator(N, normalvariate, (0.0, 1.0))
_test_generator(N, lognormvariate, (0.0, 1.0))
_test_generator(N, vonmisesvariate, (0.0, 1.0))
_test_generator(N, gammavariate, (0.01, 1.0))
_test_generator(N, gammavariate, (0.1, 1.0))
_test_generator(N, gammavariate, (0.1, 2.0))
_test_generator(N, gammavariate, (0.5, 1.0))
_test_generator(N, gammavariate, (0.9, 1.0))
_test_generator(N, gammavariate, (1.0, 1.0))
_test_generator(N, gammavariate, (2.0, 1.0))
_test_generator(N, gammavariate, (20.0, 1.0))
_test_generator(N, gammavariate, (200.0, 1.0))
_test_generator(N, gauss, (0.0, 1.0))
_test_generator(N, betavariate, (3.0, 3.0))
_test_generator(N, triangular, (0.0, 1.0, 1.0/3.0))
# Create one instance, seeded from current time, and export its methods
# as module-level functions. The functions share state across all uses
#(both in the user's code and in the Python libraries), but that's fine
# for most programs and is easier for the casual user than making them
# instantiate their own Random() instance.
_inst = Random()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
triangular = _inst.triangular
randint = _inst.randint
choice = _inst.choice
randrange = _inst.randrange
sample = _inst.sample
shuffle = _inst.shuffle
choices = _inst.choices
normalvariate = _inst.normalvariate
lognormvariate = _inst.lognormvariate
expovariate = _inst.expovariate
vonmisesvariate = _inst.vonmisesvariate
gammavariate = _inst.gammavariate
gauss = _inst.gauss
betavariate = _inst.betavariate
paretovariate = _inst.paretovariate
weibullvariate = _inst.weibullvariate
getstate = _inst.getstate
setstate = _inst.setstate
getrandbits = _inst.getrandbits
if __name__ == '__main__':
_test()

9
Lib/tempfile.py vendored
View File

@@ -42,8 +42,7 @@ import io as _io
import os as _os
import shutil as _shutil
import errno as _errno
# XXX RustPython TODO: _random
#from random import Random as _Random
from random import Random as _Random
import weakref as _weakref
try:
@@ -157,11 +156,7 @@ class _RandomNameSequence:
def __next__(self):
c = self.characters
def choose(s):
import math, random
return s[math.floor(random.random() * len(s))]
# XXX RustPython TODO: proper random impl
# choose = self.rng.choose
choose = self.rng.choice
letters = [choose(c) for dummy in range(8)]
return ''.join(letters)

View File

@@ -7,15 +7,12 @@ jobs:
pool:
vmImage: 'vs2017-win2016'
strategy:
matrix:
Python36:
python.version: '3.6'
maxParallel: 10
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(python.version)'
versionSpec: '3.7'
architecture: 'x64'
- script: |

View File

@@ -94,7 +94,7 @@ fn bench_rustpy_nbody(b: &mut test::Bencher) {
let vm = VirtualMachine::default();
let code = match vm.compile(source, compile::Mode::Single, "<stdin>".to_string()) {
let code = match vm.compile(source, compile::Mode::Single, "<stdin>".to_owned()) {
Ok(code) => code,
Err(e) => panic!("{:?}", e),
};
@@ -113,7 +113,7 @@ fn bench_rustpy_mandelbrot(b: &mut test::Bencher) {
let vm = VirtualMachine::default();
let code = match vm.compile(source, compile::Mode::Single, "<stdin>".to_string()) {
let code = match vm.compile(source, compile::Mode::Single, "<stdin>".to_owned()) {
Ok(code) => code,
Err(e) => panic!("{:?}", e),
};

View File

@@ -88,7 +88,7 @@ fn with_compiler(
) -> Result<CodeObject, CompileError> {
let mut compiler = Compiler::new(optimize);
compiler.source_path = Some(source_path);
compiler.push_new_code_object("<module>".to_string());
compiler.push_new_code_object("<module>".to_owned());
f(&mut compiler)?;
let code = compiler.pop_code_object();
trace!("Compilation completed: {:?}", code);
@@ -290,7 +290,7 @@ impl<O: OutputStream> Compiler<O> {
fn load_name(&mut self, name: &str) {
let scope = self.scope_for_name(name);
self.emit(Instruction::LoadName {
name: name.to_string(),
name: name.to_owned(),
scope,
});
}
@@ -298,7 +298,7 @@ impl<O: OutputStream> Compiler<O> {
fn store_name(&mut self, name: &str) {
let scope = self.scope_for_name(name);
self.emit(Instruction::StoreName {
name: name.to_string(),
name: name.to_owned(),
scope,
});
}
@@ -359,7 +359,7 @@ impl<O: OutputStream> Compiler<O> {
for name in names {
// import symbol from module:
self.emit(Instruction::ImportFrom {
name: name.symbol.to_string(),
name: name.symbol.to_owned(),
});
// Store module under proper name:
@@ -619,13 +619,13 @@ impl<O: OutputStream> Compiler<O> {
match &expression.node {
ast::ExpressionType::Identifier { name } => {
self.emit(Instruction::DeleteName {
name: name.to_string(),
name: name.to_owned(),
});
}
ast::ExpressionType::Attribute { value, name } => {
self.compile_expression(value)?;
self.emit(Instruction::DeleteAttr {
name: name.to_string(),
name: name.to_owned(),
});
}
ast::ExpressionType::Subscript { a, b } => {
@@ -701,7 +701,7 @@ impl<O: OutputStream> Compiler<O> {
compile_varargs(&args.kwarg),
self.source_path.clone().unwrap(),
line_number,
name.to_string(),
name.to_owned(),
));
self.enter_scope();
@@ -897,7 +897,7 @@ impl<O: OutputStream> Compiler<O> {
// key:
self.emit(Instruction::LoadConst {
value: bytecode::Constant::String {
value: "return".to_string(),
value: "return".to_owned(),
},
});
// value:
@@ -909,7 +909,7 @@ impl<O: OutputStream> Compiler<O> {
if let Some(annotation) = &arg.annotation {
self.emit(Instruction::LoadConst {
value: bytecode::Constant::String {
value: arg.arg.to_string(),
value: arg.arg.to_owned(),
},
});
self.compile_expression(&annotation)?;
@@ -982,18 +982,18 @@ impl<O: OutputStream> Compiler<O> {
Varargs::None,
self.source_path.clone().unwrap(),
line_number,
name.to_string(),
name.to_owned(),
));
self.enter_scope();
let (new_body, doc_str) = get_doc(body);
self.emit(Instruction::LoadName {
name: "__name__".to_string(),
name: "__name__".to_owned(),
scope: bytecode::NameScope::Global,
});
self.emit(Instruction::StoreName {
name: "__module__".to_string(),
name: "__module__".to_owned(),
scope: bytecode::NameScope::Free,
});
self.emit(Instruction::LoadConst {
@@ -1002,7 +1002,7 @@ impl<O: OutputStream> Compiler<O> {
},
});
self.emit(Instruction::StoreName {
name: "__qualname__".to_string(),
name: "__qualname__".to_owned(),
scope: bytecode::NameScope::Free,
});
self.compile_statements(new_body)?;
@@ -1022,7 +1022,7 @@ impl<O: OutputStream> Compiler<O> {
});
self.emit(Instruction::LoadConst {
value: bytecode::Constant::String {
value: name.to_string(),
value: name.to_owned(),
},
});
@@ -1044,7 +1044,7 @@ impl<O: OutputStream> Compiler<O> {
for keyword in keywords {
if let Some(name) = &keyword.name {
kwarg_names.push(bytecode::Constant::String {
value: name.to_string(),
value: name.to_owned(),
});
} else {
// This means **kwargs!
@@ -1090,7 +1090,7 @@ impl<O: OutputStream> Compiler<O> {
self.emit(Instruction::Rotate { amount: 2 });
self.emit(Instruction::StoreAttr {
name: "__doc__".to_string(),
name: "__doc__".to_owned(),
});
}
@@ -1171,7 +1171,7 @@ impl<O: OutputStream> Compiler<O> {
self.set_label(check_asynciter_label);
self.emit(Instruction::Duplicate);
self.emit(Instruction::LoadName {
name: "StopAsyncIteration".to_string(),
name: "StopAsyncIteration".to_owned(),
scope: bytecode::NameScope::Global,
});
self.emit(Instruction::CompareOperation {
@@ -1308,7 +1308,7 @@ impl<O: OutputStream> Compiler<O> {
});
self.emit(Instruction::LoadConst {
value: bytecode::Constant::String {
value: name.to_string(),
value: name.to_owned(),
},
});
self.emit(Instruction::StoreSubscript);
@@ -1332,7 +1332,7 @@ impl<O: OutputStream> Compiler<O> {
ast::ExpressionType::Attribute { value, name } => {
self.compile_expression(value)?;
self.emit(Instruction::StoreAttr {
name: name.to_string(),
name: name.to_owned(),
});
}
ast::ExpressionType::List { elements } | ast::ExpressionType::Tuple { elements } => {
@@ -1605,7 +1605,7 @@ impl<O: OutputStream> Compiler<O> {
Attribute { value, name } => {
self.compile_expression(value)?;
self.emit(Instruction::LoadAttr {
name: name.to_string(),
name: name.to_owned(),
});
}
Compare { vals, ops } => {
@@ -1732,7 +1732,7 @@ impl<O: OutputStream> Compiler<O> {
func: FunctionContext::Function,
};
let name = "<lambda>".to_string();
let name = "<lambda>".to_owned();
self.enter_function(&name, args)?;
self.compile_expression(body)?;
self.emit(Instruction::ReturnValue);
@@ -1795,7 +1795,7 @@ impl<O: OutputStream> Compiler<O> {
if let Some(name) = &keyword.name {
self.emit(Instruction::LoadConst {
value: bytecode::Constant::String {
value: name.to_string(),
value: name.to_owned(),
},
});
self.compile_expression(&keyword.value)?;
@@ -1858,7 +1858,7 @@ impl<O: OutputStream> Compiler<O> {
for keyword in keywords {
if let Some(name) = &keyword.name {
kwarg_names.push(bytecode::Constant::String {
value: name.to_string(),
value: name.to_owned(),
});
} else {
// This means **kwargs!
@@ -1927,13 +1927,13 @@ impl<O: OutputStream> Compiler<O> {
ast::ComprehensionKind::Set { .. } => "<setcomp>",
ast::ComprehensionKind::Dict { .. } => "<dictcomp>",
}
.to_string();
.to_owned();
let line_number = self.get_source_line_number();
// Create magnificent function <listcomp>:
self.push_output(CodeObject::new(
Default::default(),
vec![".0".to_string()],
vec![".0".to_owned()],
Varargs::None,
vec![],
Varargs::None,
@@ -2099,7 +2099,7 @@ impl<O: OutputStream> Compiler<O> {
ast::StringGroup::Constant { value } => {
self.emit(Instruction::LoadConst {
value: bytecode::Constant::String {
value: value.to_string(),
value: value.to_owned(),
},
});
}
@@ -2264,9 +2264,9 @@ mod tests {
fn compile_exec(source: &str) -> CodeObject {
let mut compiler: Compiler = Default::default();
compiler.source_path = Some("source_path".to_string());
compiler.push_new_code_object("<module>".to_string());
let ast = parser::parse_program(&source.to_string()).unwrap();
compiler.source_path = Some("source_path".to_owned());
compiler.push_new_code_object("<module>".to_owned());
let ast = parser::parse_program(source).unwrap();
let symbol_scope = make_symbol_table(&ast).unwrap();
compiler.compile_program(&ast, symbol_scope).unwrap();
compiler.pop_code_object()

View File

@@ -62,7 +62,7 @@ impl CompileError {
match parse {
ParseErrorType::Lexical(LexicalErrorType::IndentationError) => true,
ParseErrorType::UnrecognizedToken(token, expected) => {
*token == Tok::Indent || expected.clone() == Some("Indent".to_string())
*token == Tok::Indent || expected.clone() == Some("Indent".to_owned())
}
_ => false,
}
@@ -88,14 +88,14 @@ impl fmt::Display for CompileError {
let error_desc = match &self.error {
CompileErrorType::Assign(target) => format!("can't assign to {}", target),
CompileErrorType::Delete(target) => format!("can't delete {}", target),
CompileErrorType::ExpectExpr => "Expecting expression, got statement".to_string(),
CompileErrorType::ExpectExpr => "Expecting expression, got statement".to_owned(),
CompileErrorType::Parse(err) => err.to_string(),
CompileErrorType::SyntaxError(err) => err.to_string(),
CompileErrorType::StarArgs => "Two starred expressions in assignment".to_string(),
CompileErrorType::InvalidBreak => "'break' outside loop".to_string(),
CompileErrorType::InvalidContinue => "'continue' outside loop".to_string(),
CompileErrorType::InvalidReturn => "'return' outside function".to_string(),
CompileErrorType::InvalidYield => "'yield' outside function".to_string(),
CompileErrorType::StarArgs => "Two starred expressions in assignment".to_owned(),
CompileErrorType::InvalidBreak => "'break' outside loop".to_owned(),
CompileErrorType::InvalidContinue => "'continue' outside loop".to_owned(),
CompileErrorType::InvalidReturn => "'return' outside function".to_owned(),
CompileErrorType::InvalidYield => "'yield' outside function".to_owned(),
};
if let Some(statement) = &self.statement {

View File

@@ -105,7 +105,7 @@ pub struct Symbol {
impl Symbol {
fn new(name: &str) -> Self {
Symbol {
name: name.to_string(),
name: name.to_owned(),
// table,
scope: SymbolScope::Unknown,
is_param: false,
@@ -304,7 +304,7 @@ impl SymbolTableBuilder {
}
fn enter_scope(&mut self, name: &str, typ: SymbolTableType, line_number: usize) {
let table = SymbolTable::new(name.to_string(), typ, line_number);
let table = SymbolTable::new(name.to_owned(), typ, line_number);
self.tables.push(table);
}
@@ -793,7 +793,7 @@ impl SymbolTableBuilder {
// Insert symbol when required:
if !containing {
let symbol = Symbol::new(name);
table.symbols.insert(name.to_string(), symbol);
table.symbols.insert(name.to_owned(), symbol);
}
// Set proper flags on symbol:

View File

@@ -128,7 +128,7 @@ impl CompilationSource {
let module_name = if is_init {
parent.clone()
} else if parent.is_empty() {
stem.to_string()
stem.to_owned()
} else {
format!("{}.{}", parent, stem)
};
@@ -235,7 +235,7 @@ impl PyCompileInput {
})?
.compile(
mode.unwrap_or(compile::Mode::Exec),
module_name.unwrap_or_else(|| "frozen".to_string()),
module_name.unwrap_or_else(|| "frozen".to_owned()),
)
}
}

View File

@@ -224,7 +224,7 @@ impl Class {
} else {
Err(Diagnostic::span_error(
span,
"Duplicate #[py*] attribute on pyimpl".to_string(),
"Duplicate #[py*] attribute on pyimpl".to_owned(),
))
}
}
@@ -337,17 +337,16 @@ impl Class {
};
if name == "pymethod" {
self.add_item(Self::extract_method(sig, meta)?, meta_span)?;
attr_idxs.push(i);
} else if name == "pyclassmethod" {
self.add_item(Self::extract_classmethod(sig, meta)?, meta_span)?;
attr_idxs.push(i);
} else if name == "pyproperty" {
self.add_item(Self::extract_property(sig, meta)?, meta_span)?;
attr_idxs.push(i);
} else if name == "pyslot" {
self.add_item(Self::extract_slot(sig, meta)?, meta_span)?;
attr_idxs.push(i);
} else {
continue;
}
attr_idxs.push(i);
}
let mut i = 0;
let mut attr_idxs = &*attr_idxs;
@@ -406,8 +405,8 @@ fn extract_impl_items(mut items: Vec<ItemSig>) -> Result<TokenStream2, Diagnosti
let properties = properties
.into_iter()
.map(|(name, prop)| {
let getter = match prop.0 {
Some(getter) => getter,
let getter_func = match prop.0 {
Some(func) => func,
None => {
push_err_span!(
diagnostics,
@@ -418,14 +417,17 @@ fn extract_impl_items(mut items: Vec<ItemSig>) -> Result<TokenStream2, Diagnosti
return TokenStream2::new();
}
};
let add_setter = prop.1.map(|setter| quote!(.add_setter(Self::#setter)));
let (new, setter) = match prop.1 {
Some(func) => (quote! { with_get_set }, quote! { , &Self::#func }),
None => (quote! { with_get }, quote! { }),
};
let str_name = name.to_string();
quote! {
class.set_str_attr(
#name,
::rustpython_vm::obj::objproperty::PropertyBuilder::new(ctx)
.add_getter(Self::#getter)
#add_setter
.create(),
::rustpython_vm::pyobject::PyObject::new(
::rustpython_vm::obj::objgetset::PyGetSet::#new(#str_name.into(), &Self::#getter_func #setter),
ctx.getset_type(), None)
);
}
})
@@ -453,8 +455,13 @@ fn extract_impl_items(mut items: Vec<ItemSig>) -> Result<TokenStream2, Diagnosti
slot_ident,
item_ident,
} => {
let transform = if vec!["new", "call"].contains(&slot_ident.to_string().as_str()) {
quote! { ::rustpython_vm::function::IntoPyNativeFunc::into_func }
} else {
quote! { Box::new }
};
let into_func = quote_spanned! {item_ident.span()=>
::rustpython_vm::function::IntoPyNativeFunc::into_func(Self::#item_ident)
#transform(Self::#item_ident)
};
Some(quote! {
(*class.slots.borrow_mut()).#slot_ident = Some(#into_func);
@@ -620,7 +627,7 @@ fn generate_class_def(
let meta = attr.parse_meta().expect("expected doc attr to be a meta");
if let Meta::NameValue(name_value) = meta {
if let Lit::Str(s) = name_value.lit {
let val = s.value().trim().to_string();
let val = s.value().trim().to_owned();
match doc {
Some(ref mut doc) => doc.push(val),
None => doc = Some(vec![val]),
@@ -685,7 +692,8 @@ pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result<TokenSt
let property = quote! {
class.set_str_attr(
#field_name_str,
ctx.new_property(
ctx.new_readonly_getset(
#field_name_str,
|zelf: &::rustpython_vm::obj::objtuple::PyTuple,
_vm: &::rustpython_vm::VirtualMachine| {
zelf.fast_getitem(#idx)

View File

@@ -10,7 +10,7 @@ fn main() -> vm::pyobject::PyResult<()> {
.compile(
r#"print("Hello World!")"#,
compiler::compile::Mode::Exec,
"<embedded>".to_string(),
"<embedded>".to_owned(),
)
.map_err(|err| vm.new_syntax_error(&err))?;

View File

@@ -96,7 +96,7 @@ fn main() -> vm::pyobject::PyResult<()> {
.compile(
&input,
compiler::compile::Mode::Single,
"<embedded>".to_string(),
"<embedded>".to_owned(),
)
.map_err(|err| vm.new_syntax_error(&err))
.and_then(|code_obj| vm.run_code_obj(code_obj, scope.clone()))

View File

@@ -78,7 +78,7 @@ fn parse_python_file(filename: &Path) -> ParsedFile {
match std::fs::read_to_string(filename) {
Err(e) => ParsedFile {
// filename: Box::new(filename.to_path_buf()),
// code: "".to_string(),
// code: "".to_owned(),
num_lines: 0,
result: Err(e.to_string()),
},

View File

@@ -191,7 +191,7 @@ impl fmt::Display for ParseErrorType {
ParseErrorType::UnrecognizedToken(ref tok, ref expected) => {
if *tok == Tok::Indent {
write!(f, "unexpected indent")
} else if expected.clone() == Some("Indent".to_string()) {
} else if expected.clone() == Some("Indent".to_owned()) {
write!(f, "expected an indented block")
} else {
write!(f, "Got unexpected token {}", tok)

View File

@@ -83,7 +83,7 @@ impl<'a> FStringParser<'a> {
}))
} else {
spec = Some(Box::new(Constant {
value: spec_expression.to_string(),
value: spec_expression.to_owned(),
}))
}
}
@@ -274,7 +274,7 @@ mod tests {
value: Box::new(mk_ident("foo", 1, 1)),
conversion: None,
spec: Some(Box::new(Constant {
value: "spec".to_string(),
value: "spec".to_owned(),
})),
}
);

View File

@@ -303,7 +303,7 @@ where
if self.chr0 == Some('.') {
if self.chr1 == Some('_') {
return Err(LexicalError {
error: LexicalErrorType::OtherError("Invalid Syntax".to_string()),
error: LexicalErrorType::OtherError("Invalid Syntax".to_owned()),
location: self.get_pos(),
});
}
@@ -352,7 +352,7 @@ where
let value = value_text.parse::<BigInt>().unwrap();
if start_is_zero && !value.is_zero() {
return Err(LexicalError {
error: LexicalErrorType::OtherError("Invalid Token".to_string()),
error: LexicalErrorType::OtherError("Invalid Token".to_owned()),
location: self.get_pos(),
});
}
@@ -643,7 +643,7 @@ where
// This is technically stricter than python3 but spaces after
// tabs is even more insane than mixing spaces and tabs.
return Some(Err(LexicalError {
error: LexicalErrorType::OtherError("Spaces not allowed as part of indentation after tabs".to_string()),
error: LexicalErrorType::OtherError("Spaces not allowed as part of indentation after tabs".to_owned()),
location: self.get_pos(),
}));
}
@@ -658,7 +658,7 @@ where
// tabs is even more insane than mixing spaces and tabs.
return Err(LexicalError {
error: LexicalErrorType::OtherError(
"Tabs not allowed as part of indentation after spaces".to_string(),
"Tabs not allowed as part of indentation after spaces".to_owned(),
),
location: self.get_pos(),
});
@@ -1313,11 +1313,11 @@ mod tests {
tokens,
vec![
Tok::String {
value: "\\\\".to_string(),
value: "\\\\".to_owned(),
is_fstring: false,
},
Tok::String {
value: "\\".to_string(),
value: "\\".to_owned(),
is_fstring: false,
},
Tok::Newline,

View File

@@ -213,7 +213,7 @@ mod tests {
function: Box::new(mk_ident("my_func", 1, 1)),
args: vec![make_string("positional", 1, 10)],
keywords: vec![ast::Keyword {
name: Some("keyword".to_string()),
name: Some("keyword".to_owned()),
value: make_int(2, 1, 31),
}],
}

View File

@@ -57,7 +57,7 @@ fn main() {
1 => match_class!(match args.as_slice()[0].clone() {
i @ PyInt => {
use num_traits::cast::ToPrimitive;
process::exit(i.as_bigint().to_i32().unwrap());
process::exit(i.as_bigint().to_i32().unwrap_or(0));
}
arg => {
if vm.is_none(&arg) {
@@ -364,7 +364,7 @@ fn run_rustpython(vm: &VirtualMachine, matches: &ArgMatches) -> PyResult<()> {
// Figure out if a -c option was given:
if let Some(command) = matches.value_of("c") {
run_command(&vm, scope, command.to_string())?;
run_command(&vm, scope, command.to_owned())?;
} else if let Some(module) = matches.value_of("m") {
run_module(&vm, module)?;
} else if let Some(filename) = matches.value_of("script") {
@@ -389,7 +389,7 @@ fn _run_string(vm: &VirtualMachine, scope: Scope, source: &str, source_path: Str
fn run_command(vm: &VirtualMachine, scope: Scope, source: String) -> PyResult<()> {
debug!("Running command {}", source);
_run_string(vm, scope, &source, "<stdin>".to_string())?;
_run_string(vm, scope, &source, "<stdin>".to_owned())?;
Ok(())
}
@@ -426,13 +426,13 @@ fn run_script(vm: &VirtualMachine, scope: Scope, script_file: &str) -> PyResult<
process::exit(1);
};
let dir = file_path.parent().unwrap().to_str().unwrap().to_string();
let dir = file_path.parent().unwrap().to_str().unwrap().to_owned();
let sys_path = vm.get_attribute(vm.sys_module.clone(), "path").unwrap();
vm.call_method(&sys_path, "insert", vec![vm.new_int(0), vm.new_str(dir)])?;
match util::read_file(&file_path) {
Ok(source) => {
_run_string(vm, scope, &source, file_path.to_str().unwrap().to_string())?;
_run_string(vm, scope, &source, file_path.to_str().unwrap().to_owned())?;
}
Err(err) => {
error!(

View File

@@ -21,7 +21,7 @@ enum ShellExecResult {
}
fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> ShellExecResult {
match vm.compile(source, compile::Mode::Single, "<stdin>".to_string()) {
match vm.compile(source, compile::Mode::Single, "<stdin>".to_owned()) {
Ok(code) => {
match vm.run_code_obj(code, scope.clone()) {
Ok(value) => {

View File

@@ -159,7 +159,7 @@ impl Completer for ShellHelper<'_> {
.complete_opt(&line[0..pos])
// as far as I can tell, there's no better way to do both completion
// and indentation (or even just indentation)
.unwrap_or_else(|| (line.len(), vec!["\t".to_string()])))
.unwrap_or_else(|| (line.len(), vec!["\t".to_owned()])))
}
}

View File

@@ -65,3 +65,11 @@ try:
raise NewException("test")
except NewException as e:
assert e.value == "test"
exc = SyntaxError('msg', 1, 2, 3, 4, 5)
assert exc.msg == 'msg'
assert exc.filename is None
assert exc.lineno is None
assert exc.offset is None
assert exc.text is None

View File

@@ -0,0 +1,29 @@
import random
random.seed(1234)
# random.randint
assert random.randint(1, 11) == 8
# random.shuffle
left = list(range(10))
right = [2, 7, 3, 5, 8, 4, 6, 9, 0, 1]
random.shuffle(left)
assert left == right
# random.choice
assert random.choice(left) == 5
# random.choices
expected = ['red', 'green', 'red', 'black', 'black', 'red']
result = random.choices(['red', 'black', 'green'], [18, 18, 2], k=6)
assert expected == result
# random.sample
sampled = [0, 2, 1]
assert random.sample(list(range(3)), 3) == sampled
# TODO : random.random(), random.uniform(), random.triangular(),
# random.betavariate, random.expovariate, random.gammavariate,
# random.gauss, random.lognormvariate, random.normalvariate,
# random.vonmisesvariate, random.paretovariate, random.weibullvariate

View File

@@ -86,3 +86,7 @@ class C(B, BB):
pass
assert C.mro() == [C, B, A, BB, AA, object]
assert type(Exception.args).__name__ == 'getset_descriptor'
assert type(None).__bool__(None) is False

View File

@@ -31,7 +31,7 @@ num-integer = "0.1.41"
num-rational = "0.2.2"
num-iter = "0.1.39"
rand = "0.7"
rand_distr = "0.2"
rand_core = "0.5"
getrandom = "0.1"
log = "0.4"
rustpython-derive = {path = "../derive", version = "0.1.1"}

View File

@@ -87,7 +87,7 @@ pub fn to_ascii(value: &str) -> String {
ascii
}
fn builtin_bin(x: PyIntRef, _vm: &VirtualMachine) -> String {
fn builtin_bin(x: PyIntRef) -> String {
let x = x.as_bigint();
if x.is_negative() {
format!("-0b{:b}", x.abs())
@@ -105,7 +105,7 @@ fn builtin_callable(obj: PyObjectRef, vm: &VirtualMachine) -> bool {
fn builtin_chr(i: u32, vm: &VirtualMachine) -> PyResult<String> {
match char::from_u32(i) {
Some(value) => Ok(value.to_string()),
None => Err(vm.new_value_error("chr() arg not in range(0x110000)".to_string())),
None => Err(vm.new_value_error("chr() arg not in range(0x110000)".to_owned())),
}
}
@@ -146,7 +146,7 @@ fn builtin_compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult {
.parse::<compile::Mode>()
.map_err(|err| vm.new_value_error(err.to_string()))?;
vm.compile(&source, mode, args.filename.as_str().to_string())
vm.compile(&source, mode, args.filename.as_str().to_owned())
.map(|o| o.into_object())
.map_err(|err| vm.new_syntax_error(&err))
}
@@ -229,7 +229,7 @@ fn run_code(
// Determine code object:
let code_obj = match source {
Either::A(string) => vm
.compile(string.as_str(), mode, "<string>".to_string())
.compile(string.as_str(), mode, "<string>".to_owned())
.map_err(|err| vm.new_syntax_error(&err))?,
Either::B(code_obj) => code_obj,
};
@@ -343,7 +343,7 @@ fn builtin_hex(number: PyIntRef, vm: &VirtualMachine) -> PyResult {
Ok(vm.new_str(s))
}
fn builtin_id(obj: PyObjectRef, _vm: &VirtualMachine) -> usize {
fn builtin_id(obj: PyObjectRef) -> usize {
obj.get_id()
}
@@ -391,7 +391,7 @@ fn builtin_len(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
fn builtin_locals(vm: &VirtualMachine) -> PyDictRef {
let locals = vm.get_locals();
locals.copy(vm).into_ref(vm)
locals.copy().into_ref(vm)
}
fn builtin_max(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -400,14 +400,14 @@ fn builtin_max(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
std::cmp::Ordering::Equal => vm.extract_elements(&args.args[0])?,
std::cmp::Ordering::Less => {
// zero arguments means type error:
return Err(vm.new_type_error("Expected 1 or more arguments".to_string()));
return Err(vm.new_type_error("Expected 1 or more arguments".to_owned()));
}
};
if candidates.is_empty() {
let default = args.get_optional_kwarg("default");
return default
.ok_or_else(|| vm.new_value_error("max() arg is an empty sequence".to_string()));
.ok_or_else(|| vm.new_value_error("max() arg is an empty sequence".to_owned()));
}
let key_func = args.get_optional_kwarg("key");
@@ -446,14 +446,14 @@ fn builtin_min(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
std::cmp::Ordering::Equal => vm.extract_elements(&args.args[0])?,
std::cmp::Ordering::Less => {
// zero arguments means type error:
return Err(vm.new_type_error("Expected 1 or more arguments".to_string()));
return Err(vm.new_type_error("Expected 1 or more arguments".to_owned()));
}
};
if candidates.is_empty() {
let default = args.get_optional_kwarg("default");
return default
.ok_or_else(|| vm.new_value_error("min() arg is an empty sequence".to_string()));
.ok_or_else(|| vm.new_value_error("min() arg is an empty sequence".to_owned()));
}
let key_func = args.get_optional_kwarg("key");
@@ -540,7 +540,7 @@ fn builtin_ord(string: Either<PyByteInner, PyStringRef>, vm: &VirtualMachine) ->
match string.chars().next() {
Some(character) => Ok(character as u32),
None => Err(vm.new_type_error(
"ord() could not guess the integer representing this character".to_string(),
"ord() could not guess the integer representing this character".to_owned(),
)),
}
}
@@ -565,18 +565,18 @@ fn builtin_pow(
&& objtype::isinstance(&y, &vm.ctx.int_type()))
{
return Err(vm.new_type_error(
"pow() 3rd argument not allowed unless all arguments are integers".to_string(),
"pow() 3rd argument not allowed unless all arguments are integers".to_owned(),
));
}
let y = objint::get_value(&y);
if y.sign() == Sign::Minus {
return Err(vm.new_value_error(
"pow() 2nd argument cannot be negative when 3rd argument specified".to_string(),
"pow() 2nd argument cannot be negative when 3rd argument specified".to_owned(),
));
}
let m = m.as_bigint();
if m.is_zero() {
return Err(vm.new_value_error("pow() 3rd argument cannot be 0".to_string()));
return Err(vm.new_value_error("pow() 3rd argument cannot be 0".to_owned()));
}
let x = objint::get_value(&x);
Ok(vm.new_int(x.modpow(&y, &m)))
@@ -675,7 +675,7 @@ fn builtin_reversed(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
vm.invoke(&reversed_method?, PyFuncArgs::default())
} else {
vm.get_method_or_type_error(obj.clone(), "__getitem__", || {
"argument to reversed() must be a sequence".to_string()
"argument to reversed() must be a sequence".to_owned()
})?;
let len = vm.call_method(&obj.clone(), "__len__", PyFuncArgs::default())?;
let obj_iterator = objiter::PySequenceIterator {
@@ -920,7 +920,7 @@ pub fn builtin_build_class_(
vm: &VirtualMachine,
) -> PyResult {
let name = qualified_name.as_str().split('.').next_back().unwrap();
let name_obj = vm.new_str(name.to_string());
let name_obj = vm.new_str(name.to_owned());
let mut metaclass = if let Some(metaclass) = kwargs.pop_kwarg("metaclass") {
PyClassRef::try_from_object(vm, metaclass)?

View File

@@ -236,10 +236,10 @@ impl CFormatSpec {
format!("{:.*}", precision, magnitude)
}
CFormatType::Float(CFloatType::Exponent(_)) => {
return Err("Not yet implemented for %e and %E".to_string())
return Err("Not yet implemented for %e and %E".to_owned())
}
CFormatType::Float(CFloatType::General(_)) => {
return Err("Not yet implemented for %g and %G".to_string())
return Err("Not yet implemented for %g and %G".to_owned())
}
_ => unreachable!(),
};
@@ -623,36 +623,36 @@ mod tests {
"%10s"
.parse::<CFormatSpec>()
.unwrap()
.format_string("test".to_string()),
" test".to_string()
.format_string("test".to_owned()),
" test".to_owned()
);
assert_eq!(
"%-10s"
.parse::<CFormatSpec>()
.unwrap()
.format_string("test".to_string()),
"test ".to_string()
.format_string("test".to_owned()),
"test ".to_owned()
);
assert_eq!(
"%#10x"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(0x1337)),
" 0x1337".to_string()
" 0x1337".to_owned()
);
assert_eq!(
"%-#10x"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(0x1337)),
"0x1337 ".to_string()
"0x1337 ".to_owned()
);
}
#[test]
fn test_parse_key() {
let expected = Ok(CFormatSpec {
mapping_key: Some("amount".to_string()),
mapping_key: Some("amount".to_owned()),
format_type: CFormatType::Number(CNumberType::Decimal),
format_char: 'd',
chars_consumed: 10,
@@ -663,7 +663,7 @@ mod tests {
assert_eq!("%(amount)d".parse::<CFormatSpec>(), expected);
let expected = Ok(CFormatSpec {
mapping_key: Some("m((u(((l((((ti))))p)))l))e".to_string()),
mapping_key: Some("m((u(((l((((ti))))p)))l))e".to_owned()),
format_type: CFormatType::Number(CNumberType::Decimal),
format_char: 'd',
chars_consumed: 30,
@@ -725,7 +725,7 @@ mod tests {
assert_eq!(parsed, expected);
assert_eq!(
parsed.unwrap().format_number(&BigInt::from(12)),
"+12 ".to_string()
"+12 ".to_owned()
);
}
@@ -735,15 +735,15 @@ mod tests {
"%5.4s"
.parse::<CFormatSpec>()
.unwrap()
.format_string("Hello, World!".to_string()),
" Hell".to_string()
.format_string("Hello, World!".to_owned()),
" Hell".to_owned()
);
assert_eq!(
"%-5.4s"
.parse::<CFormatSpec>()
.unwrap()
.format_string("Hello, World!".to_string()),
"Hell ".to_string()
.format_string("Hello, World!".to_owned()),
"Hell ".to_owned()
);
}
@@ -753,8 +753,8 @@ mod tests {
"%.2s"
.parse::<CFormatSpec>()
.unwrap()
.format_string("❤❤❤❤❤❤❤❤".to_string()),
"❤❤".to_string()
.format_string("❤❤❤❤❤❤❤❤".to_owned()),
"❤❤".to_owned()
);
}
@@ -765,56 +765,56 @@ mod tests {
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(27)),
"00027".to_string()
"00027".to_owned()
);
assert_eq!(
"%+05d"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(27)),
"+0027".to_string()
"+0027".to_owned()
);
assert_eq!(
"%-d"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(-27)),
"-27".to_string()
"-27".to_owned()
);
assert_eq!(
"% d"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(27)),
" 27".to_string()
" 27".to_owned()
);
assert_eq!(
"% d"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(-27)),
"-27".to_string()
"-27".to_owned()
);
assert_eq!(
"%08x"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(0x1337)),
"00001337".to_string()
"00001337".to_owned()
);
assert_eq!(
"%#010x"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(0x1337)),
"0x00001337".to_string()
"0x00001337".to_owned()
);
assert_eq!(
"%-#010x"
.parse::<CFormatSpec>()
.unwrap()
.format_number(&BigInt::from(0x1337)),
"0x1337 ".to_string()
"0x1337 ".to_owned()
);
}
@@ -825,7 +825,7 @@ mod tests {
.unwrap()
.format_float(f64::from(1.2345))
.ok(),
Some("1.234500".to_string())
Some("1.234500".to_owned())
);
assert_eq!(
"%+f"
@@ -833,7 +833,7 @@ mod tests {
.unwrap()
.format_float(f64::from(1.2345))
.ok(),
Some("+1.234500".to_string())
Some("+1.234500".to_owned())
);
assert_eq!(
"% f"
@@ -841,21 +841,21 @@ mod tests {
.unwrap()
.format_float(f64::from(1.2345))
.ok(),
Some(" 1.234500".to_string())
Some(" 1.234500".to_owned())
);
assert_eq!(
"%f".parse::<CFormatSpec>()
.unwrap()
.format_float(f64::from(-1.2345))
.ok(),
Some("-1.234500".to_string())
Some("-1.234500".to_owned())
);
assert_eq!(
"%f".parse::<CFormatSpec>()
.unwrap()
.format_float(f64::from(1.2345678901))
.ok(),
Some("1.234568".to_string())
Some("1.234568".to_owned())
);
}
@@ -864,7 +864,7 @@ mod tests {
let fmt = "Hello, my name is %s and I'm %d years old";
let expected = Ok(CFormatString {
format_parts: vec![
(0, CFormatPart::Literal("Hello, my name is ".to_string())),
(0, CFormatPart::Literal("Hello, my name is ".to_owned())),
(
18,
CFormatPart::Spec(CFormatSpec {
@@ -877,7 +877,7 @@ mod tests {
flags: CConversionFlags::empty(),
}),
),
(20, CFormatPart::Literal(" and I'm ".to_string())),
(20, CFormatPart::Literal(" and I'm ".to_owned())),
(
29,
CFormatPart::Spec(CFormatSpec {
@@ -890,7 +890,7 @@ mod tests {
flags: CConversionFlags::empty(),
}),
),
(31, CFormatPart::Literal(" years old".to_string())),
(31, CFormatPart::Literal(" years old".to_owned())),
],
});
let result = fmt.parse::<CFormatString>();

View File

@@ -344,7 +344,7 @@ impl DictKey for &PyObjectRef {
impl DictKey for &str {
fn do_hash(self, _vm: &VirtualMachine) -> PyResult<HashValue> {
// follow a similar route as the hashing of PyStringRef
let raw_hash = pyhash::hash_value(&self.to_string()).to_bigint().unwrap();
let raw_hash = pyhash::hash_value(&self.to_owned()).to_bigint().unwrap();
let raw_hash = pyhash::hash_bigint(&raw_hash);
let mut hasher = DefaultHasher::new();
raw_hash.hash(&mut hasher);
@@ -362,7 +362,7 @@ impl DictKey for &str {
Ok(py_str_value.as_str() == self)
} else {
// Fall back to PyString implementation.
let s = vm.new_str(self.to_string());
let s = vm.new_str(self.to_owned());
s.do_eq(vm, other_key)
}
}
@@ -393,12 +393,12 @@ mod tests {
assert_eq!(0, dict.len());
let key1 = vm.new_bool(true);
let value1 = vm.new_str("abc".to_string());
let value1 = vm.new_str("abc".to_owned());
dict.insert(&vm, &key1, value1.clone()).unwrap();
assert_eq!(1, dict.len());
let key2 = vm.new_str("x".to_string());
let value2 = vm.new_str("def".to_string());
let key2 = vm.new_str("x".to_owned());
let value2 = vm.new_str("def".to_owned());
dict.insert(&vm, &key2, value2.clone()).unwrap();
assert_eq!(2, dict.len());
@@ -438,7 +438,7 @@ mod tests {
fn check_hash_equivalence(text: &str) {
let vm: VirtualMachine = Default::default();
let value1 = text;
let value2 = vm.new_str(value1.to_string());
let value2 = vm.new_str(value1.to_owned());
let hash1 = value1.do_hash(&vm).expect("Hash should not fail.");
let hash2 = value2.do_hash(&vm).expect("Hash should not fail.");

View File

@@ -4,7 +4,7 @@ use crate::vm::VirtualMachine;
use rustpython_compiler::compile;
pub fn eval(vm: &VirtualMachine, source: &str, scope: Scope, source_path: &str) -> PyResult {
match vm.compile(source, compile::Mode::Eval, source_path.to_string()) {
match vm.compile(source, compile::Mode::Eval, source_path.to_owned()) {
Ok(bytecode) => {
debug!("Code object: {:?}", bytecode);
vm.run_code_obj(bytecode, scope)

View File

@@ -67,8 +67,8 @@ impl PyBaseException {
Ok(())
}
#[pyproperty(name = "args")]
fn get_args(&self, _vm: &VirtualMachine) -> PyTupleRef {
#[pyproperty]
pub fn args(&self) -> PyTupleRef {
self.args.borrow().clone()
}
@@ -80,7 +80,7 @@ impl PyBaseException {
}
#[pyproperty(name = "__traceback__")]
fn get_traceback(&self, _vm: &VirtualMachine) -> Option<PyTracebackRef> {
pub fn traceback(&self) -> Option<PyTracebackRef> {
self.traceback.borrow().clone()
}
@@ -90,41 +90,37 @@ impl PyBaseException {
}
#[pyproperty(name = "__cause__")]
fn get_cause(&self, _vm: &VirtualMachine) -> Option<PyBaseExceptionRef> {
pub fn cause(&self) -> Option<PyBaseExceptionRef> {
self.cause.borrow().clone()
}
#[pyproperty(name = "__cause__", setter)]
fn setter_cause(&self, cause: Option<PyBaseExceptionRef>, _vm: &VirtualMachine) {
pub fn set_cause(&self, cause: Option<PyBaseExceptionRef>) {
self.cause.replace(cause);
}
#[pyproperty(name = "__context__")]
fn get_context(&self, _vm: &VirtualMachine) -> Option<PyBaseExceptionRef> {
pub fn context(&self) -> Option<PyBaseExceptionRef> {
self.context.borrow().clone()
}
#[pyproperty(name = "__context__", setter)]
fn setter_context(&self, context: Option<PyBaseExceptionRef>, _vm: &VirtualMachine) {
pub fn set_context(&self, context: Option<PyBaseExceptionRef>) {
self.context.replace(context);
}
#[pyproperty(name = "__suppress_context__")]
fn get_suppress_context(&self, _vm: &VirtualMachine) -> bool {
fn get_suppress_context(&self) -> bool {
self.suppress_context.get()
}
#[pyproperty(name = "__suppress_context__", setter)]
fn set_suppress_context(&self, suppress_context: bool, _vm: &VirtualMachine) {
fn set_suppress_context(&self, suppress_context: bool) {
self.suppress_context.set(suppress_context);
}
#[pymethod]
fn with_traceback(
zelf: PyRef<Self>,
tb: Option<PyTracebackRef>,
_vm: &VirtualMachine,
) -> PyResult {
fn with_traceback(zelf: PyRef<Self>, tb: Option<PyTracebackRef>) -> PyResult {
zelf.traceback.replace(tb);
Ok(zelf.as_object().clone())
}
@@ -148,28 +144,6 @@ impl PyBaseException {
Err(i) => format!("{}({})", cls.name, i.format(", ")),
}
}
pub fn args(&self) -> PyTupleRef {
self.args.borrow().clone()
}
pub fn traceback(&self) -> Option<PyTracebackRef> {
self.traceback.borrow().clone()
}
pub fn cause(&self) -> Option<PyBaseExceptionRef> {
self.cause.borrow().clone()
}
pub fn set_cause(&self, cause: Option<PyBaseExceptionRef>) {
self.cause.replace(cause);
}
pub fn context(&self) -> Option<PyBaseExceptionRef> {
self.context.borrow().clone()
}
pub fn set_context(&self, context: Option<PyBaseExceptionRef>) {
self.context.replace(context);
}
}
/// Print exception chain
@@ -225,7 +199,7 @@ fn print_source_line<W: Write>(output: &mut W, filename: &str, lineno: usize) ->
/// Print exception occurrence location from traceback element
fn write_traceback_entry<W: Write>(output: &mut W, tb_entry: &PyTracebackRef) -> io::Result<()> {
let filename = tb_entry.frame.code.source_path.to_string();
let filename = tb_entry.frame.code.source_path.to_owned();
writeln!(
output,
r##" File "{}", line {}, in {}"##,
@@ -347,7 +321,7 @@ impl ExceptionCtor {
// both are instances; which would we choose?
(Self::Instance(_exc_a), Some(_exc_b)) => {
Err(vm
.new_type_error("instance exception may not have a separate value".to_string()))
.new_type_error("instance exception may not have a separate value".to_owned()))
}
// if the "type" is an instance and the value isn't, use the "type"
(Self::Instance(exc), None) => Ok(exc),
@@ -634,20 +608,21 @@ pub fn init(ctx: &PyContext) {
PyBaseException::extend_class(ctx, &excs.base_exception_type);
extend_class!(ctx, &excs.syntax_error, {
"msg" => ctx.new_property(make_arg_getter(0)),
"filename" => ctx.new_property(make_arg_getter(1)),
"lineno" => ctx.new_property(make_arg_getter(2)),
"offset" => ctx.new_property(make_arg_getter(3)),
"text" => ctx.new_property(make_arg_getter(4)),
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
// TODO: members
"filename" => ctx.none(),
"lineno" => ctx.none(),
"offset" => ctx.none(),
"text" => ctx.none(),
});
extend_class!(ctx, &excs.import_error, {
"__init__" => ctx.new_method(import_error_init),
"msg" => ctx.new_property(make_arg_getter(0)),
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
});
extend_class!(ctx, &excs.stop_iteration, {
"value" => ctx.new_property(make_arg_getter(0)),
"value" => ctx.new_readonly_getset("value", make_arg_getter(0)),
});
extend_class!(ctx, &excs.key_error, {
@@ -655,27 +630,27 @@ pub fn init(ctx: &PyContext) {
});
extend_class!(ctx, &excs.unicode_decode_error, {
"encoding" => ctx.new_property(make_arg_getter(0)),
"object" => ctx.new_property(make_arg_getter(1)),
"start" => ctx.new_property(make_arg_getter(2)),
"end" => ctx.new_property(make_arg_getter(3)),
"reason" => ctx.new_property(make_arg_getter(4)),
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
});
extend_class!(ctx, &excs.unicode_encode_error, {
"encoding" => ctx.new_property(make_arg_getter(0)),
"object" => ctx.new_property(make_arg_getter(1)),
"start" => ctx.new_property(make_arg_getter(2)),
"end" => ctx.new_property(make_arg_getter(3)),
"reason" => ctx.new_property(make_arg_getter(4)),
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
});
extend_class!(ctx, &excs.unicode_translate_error, {
"encoding" => ctx.new_property(none_getter),
"object" => ctx.new_property(make_arg_getter(0)),
"start" => ctx.new_property(make_arg_getter(1)),
"end" => ctx.new_property(make_arg_getter(2)),
"reason" => ctx.new_property(make_arg_getter(3)),
"encoding" => ctx.new_readonly_getset("encoding", none_getter),
"object" => ctx.new_readonly_getset("object", make_arg_getter(0)),
"start" => ctx.new_readonly_getset("start", make_arg_getter(1)),
"end" => ctx.new_readonly_getset("end", make_arg_getter(2)),
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(3)),
});
}

View File

@@ -343,13 +343,13 @@ impl FormatSpec {
let magnitude = num.abs();
let raw_magnitude_string_result: Result<String, &'static str> = match self.format_type {
Some(FormatType::FixedPointUpper) => match magnitude {
magnitude if magnitude.is_nan() => Ok("NAN".to_string()),
magnitude if magnitude.is_infinite() => Ok("INF".to_string()),
magnitude if magnitude.is_nan() => Ok("NAN".to_owned()),
magnitude if magnitude.is_infinite() => Ok("INF".to_owned()),
_ => Ok(format!("{:.*}", precision, magnitude)),
},
Some(FormatType::FixedPointLower) => match magnitude {
magnitude if magnitude.is_nan() => Ok("nan".to_string()),
magnitude if magnitude.is_infinite() => Ok("inf".to_string()),
magnitude if magnitude.is_nan() => Ok("nan".to_owned()),
magnitude if magnitude.is_infinite() => Ok("inf".to_owned()),
_ => Ok(format!("{:.*}", precision, magnitude)),
},
Some(FormatType::Decimal) => Err("Unknown format code 'd' for object of type 'float'"),
@@ -377,14 +377,14 @@ impl FormatSpec {
Err("Format code 'e' for object of type 'float' not implemented yet")
}
Some(FormatType::Percentage) => match magnitude {
magnitude if magnitude.is_nan() => Ok("nan%".to_string()),
magnitude if magnitude.is_infinite() => Ok("inf%".to_string()),
magnitude if magnitude.is_nan() => Ok("nan%".to_owned()),
magnitude if magnitude.is_infinite() => Ok("inf%".to_owned()),
_ => Ok(format!("{:.*}%", precision, magnitude * 100.0)),
},
None => {
match magnitude {
magnitude if magnitude.is_nan() => Ok("nan".to_string()),
magnitude if magnitude.is_infinite() => Ok("inf".to_string()),
magnitude if magnitude.is_nan() => Ok("nan".to_owned()),
magnitude if magnitude.is_infinite() => Ok("inf".to_owned()),
// Using the Debug format here to prevent the automatic conversion of floats
// ending in .0 to their integer representation (e.g., 1.0 -> 1)
_ => Ok(format!("{:?}", magnitude)),
@@ -614,7 +614,7 @@ impl FormatString {
let arg_part = parts[0];
let format_spec = if parts.len() > 1 {
parts[1].to_string()
parts[1].to_owned()
} else {
String::new()
};
@@ -625,7 +625,7 @@ impl FormatString {
let arg_part = parts[0];
let preconversor_spec = if parts.len() > 1 {
"!".to_string() + parts[1]
"!".to_owned() + parts[1]
} else {
String::new()
};
@@ -638,7 +638,7 @@ impl FormatString {
if let Ok(index) = arg_part.parse::<usize>() {
Ok(FormatPart::IndexSpec(index, format_spec))
} else {
Ok(FormatPart::KeywordSpec(arg_part.to_string(), format_spec))
Ok(FormatPart::KeywordSpec(arg_part.to_owned(), format_spec))
}
}
@@ -766,43 +766,43 @@ mod tests {
parse_format_spec("d")
.unwrap()
.format_int(&BigInt::from_bytes_be(Sign::Plus, b"\x10")),
Ok("16".to_string())
Ok("16".to_owned())
);
assert_eq!(
parse_format_spec("x")
.unwrap()
.format_int(&BigInt::from_bytes_be(Sign::Plus, b"\x10")),
Ok("10".to_string())
Ok("10".to_owned())
);
assert_eq!(
parse_format_spec("b")
.unwrap()
.format_int(&BigInt::from_bytes_be(Sign::Plus, b"\x10")),
Ok("10000".to_string())
Ok("10000".to_owned())
);
assert_eq!(
parse_format_spec("o")
.unwrap()
.format_int(&BigInt::from_bytes_be(Sign::Plus, b"\x10")),
Ok("20".to_string())
Ok("20".to_owned())
);
assert_eq!(
parse_format_spec("+d")
.unwrap()
.format_int(&BigInt::from_bytes_be(Sign::Plus, b"\x10")),
Ok("+16".to_string())
Ok("+16".to_owned())
);
assert_eq!(
parse_format_spec("^ 5d")
.unwrap()
.format_int(&BigInt::from_bytes_be(Sign::Minus, b"\x10")),
Ok(" -16 ".to_string())
Ok(" -16 ".to_owned())
);
assert_eq!(
parse_format_spec("0>+#10x")
.unwrap()
.format_int(&BigInt::from_bytes_be(Sign::Plus, b"\x10")),
Ok("00000+0x10".to_string())
Ok("00000+0x10".to_owned())
);
}
@@ -810,10 +810,10 @@ mod tests {
fn test_format_parse() {
let expected = Ok(FormatString {
format_parts: vec![
FormatPart::Literal("abcd".to_string()),
FormatPart::Literal("abcd".to_owned()),
FormatPart::IndexSpec(1, String::new()),
FormatPart::Literal(":".to_string()),
FormatPart::KeywordSpec("key".to_string(), String::new()),
FormatPart::Literal(":".to_owned()),
FormatPart::KeywordSpec("key".to_owned(), String::new()),
],
});
@@ -832,9 +832,9 @@ mod tests {
fn test_format_parse_escape() {
let expected = Ok(FormatString {
format_parts: vec![
FormatPart::Literal("{".to_string()),
FormatPart::KeywordSpec("key".to_string(), String::new()),
FormatPart::Literal("}ddfe".to_string()),
FormatPart::Literal("{".to_owned()),
FormatPart::KeywordSpec("key".to_owned(), String::new()),
FormatPart::Literal("}ddfe".to_owned()),
],
});

View File

@@ -337,7 +337,7 @@ impl Frame {
bytecode::Instruction::ListAppend { i } => {
let list_obj = self.nth_value(*i);
let item = self.pop_value();
objlist::PyListRef::try_from_object(vm, list_obj)?.append(item, vm);
objlist::PyListRef::try_from_object(vm, list_obj)?.append(item);
Ok(None)
}
bytecode::Instruction::SetAdd { i } => {
@@ -586,7 +586,7 @@ impl Frame {
let value = self.pop_value();
let elements = vm.extract_elements(&value)?;
if elements.len() != *size {
Err(vm.new_value_error("Wrong number of values to unpack".to_string()))
Err(vm.new_value_error("Wrong number of values to unpack".to_owned()))
} else {
for element in elements.into_iter().rev() {
self.push_value(element);
@@ -985,7 +985,7 @@ impl Frame {
None => {
return Err(vm.new_exception_msg(
vm.ctx.exceptions.runtime_error.clone(),
"No active exception to reraise".to_string(),
"No active exception to reraise".to_owned(),
))
}
},
@@ -1154,7 +1154,7 @@ impl Frame {
.new_pyfunction(code_obj, scope, defaults, kw_only_defaults);
let name = qualified_name.as_str().split('.').next_back().unwrap();
vm.set_attr(&func_obj, "__name__", vm.new_str(name.to_string()))?;
vm.set_attr(&func_obj, "__name__", vm.new_str(name.to_owned()))?;
vm.set_attr(&func_obj, "__qualname__", qualified_name)?;
let module = self
.scope
@@ -1319,13 +1319,13 @@ impl Frame {
fn store_attr(&self, vm: &VirtualMachine, attr_name: &str) -> FrameResult {
let parent = self.pop_value();
let value = self.pop_value();
vm.set_attr(&parent, vm.new_str(attr_name.to_string()), value)?;
vm.set_attr(&parent, vm.new_str(attr_name.to_owned()), value)?;
Ok(None)
}
fn delete_attr(&self, vm: &VirtualMachine, attr_name: &str) -> FrameResult {
let parent = self.pop_value();
let name = vm.ctx.new_str(attr_name.to_string());
let name = vm.ctx.new_str(attr_name.to_owned());
vm.del_attr(&parent, name)?;
Ok(None)
}
@@ -1390,7 +1390,7 @@ impl fmt::Debug for Frame {
.iter()
.map(|elem| {
if elem.payload.as_any().is::<Frame>() {
"\n > {frame}".to_string()
"\n > {frame}".to_owned()
} else {
format!("\n > {:?}", elem)
}

View File

@@ -91,7 +91,7 @@ pub fn import_codeobj(
set_file_attr: bool,
) -> PyResult {
let attrs = vm.ctx.new_dict();
attrs.set_item("__name__", vm.new_str(module_name.to_string()), vm)?;
attrs.set_item("__name__", vm.new_str(module_name.to_owned()), vm)?;
if set_file_attr {
attrs.set_item("__file__", vm.new_str(code_obj.source_path.to_owned()), vm)?;
}

View File

@@ -17,6 +17,7 @@ pub mod objfloat;
pub mod objframe;
pub mod objfunction;
pub mod objgenerator;
pub mod objgetset;
pub mod objint;
pub mod objiter;
pub mod objlist;

View File

@@ -58,7 +58,7 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<bool> {
let len_val = int_obj.as_bigint();
if len_val.sign() == Sign::Minus {
return Err(
vm.new_value_error("__len__() should return >= 0".to_string())
vm.new_value_error("__len__() should return >= 0".to_owned())
);
}
@@ -96,7 +96,7 @@ The class bool is a subclass of the class int, and cannot be subclassed.";
"__rand__" => context.new_method(bool_and),
"__xor__" => context.new_method(bool_xor),
"__rxor__" => context.new_method(bool_xor),
"__doc__" => context.new_str(bool_doc.to_string()),
"__doc__" => context.new_str(bool_doc.to_owned()),
});
}
@@ -118,11 +118,11 @@ pub fn get_py_int(obj: &PyObjectRef) -> &PyInt {
&obj.payload::<PyInt>().unwrap()
}
fn bool_repr(obj: bool, _vm: &VirtualMachine) -> String {
fn bool_repr(obj: bool) -> String {
if obj {
"True".to_string()
"True".to_owned()
} else {
"False".to_string()
"False".to_owned()
}
}
@@ -134,7 +134,7 @@ fn bool_format(
if format_spec.as_str().is_empty() {
vm.to_str(&obj)
} else {
Err(vm.new_type_error("unsupported format string passed to bool.__format__".to_string()))
Err(vm.new_type_error("unsupported format string passed to bool.__format__".to_owned()))
}
}

View File

@@ -3,9 +3,9 @@ use std::fmt;
use crate::function::{OptionalArg, PyFuncArgs, PyNativeFunc};
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol,
};
use crate::slots::{PyBuiltinCallable, PyBuiltinDescriptor};
use crate::slots::{SlotCall, SlotDescriptor};
use crate::vm::VirtualMachine;
#[pyclass]
@@ -35,13 +35,13 @@ impl PyBuiltinFunction {
}
}
impl PyBuiltinCallable for PyBuiltinFunction {
impl SlotCall for PyBuiltinFunction {
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
(self.value)(vm, args)
}
}
#[pyimpl(with(PyBuiltinCallable))]
#[pyimpl(with(SlotCall))]
impl PyBuiltinFunction {}
#[pyclass]
@@ -73,13 +73,17 @@ impl PyBuiltinMethod {
}
}
impl PyBuiltinDescriptor for PyBuiltinMethod {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyBuiltinMethod {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = match Self::_check(zelf, obj, vm) {
Ok(obj) => obj,
Err(result) => return result,
};
if obj.is(&vm.get_none()) && !Self::_cls_is(&cls, &obj.class()) {
Ok(zelf.into_object())
} else {
@@ -88,13 +92,13 @@ impl PyBuiltinDescriptor for PyBuiltinMethod {
}
}
impl PyBuiltinCallable for PyBuiltinMethod {
impl SlotCall for PyBuiltinMethod {
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
(self.function.value)(vm, args)
}
}
#[pyimpl(with(PyBuiltinDescriptor, PyBuiltinCallable))]
#[pyimpl(with(SlotDescriptor, SlotCall))]
impl PyBuiltinMethod {}
pub fn init(context: &PyContext) {

View File

@@ -99,17 +99,17 @@ impl PyByteArray {
}
#[pymethod(name = "__repr__")]
fn repr(&self, _vm: &VirtualMachine) -> PyResult<String> {
fn repr(&self) -> PyResult<String> {
Ok(format!("bytearray(b'{}')", self.inner.borrow().repr()?))
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.inner.borrow().len()
}
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
fn sizeof(&self) -> usize {
size_of::<Self>() + self.inner.borrow().len() * size_of::<u8>()
}
@@ -140,11 +140,11 @@ impl PyByteArray {
#[pymethod(name = "__hash__")]
fn hash(&self, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_type_error("unhashable type: bytearray".to_string()))
Err(vm.new_type_error("unhashable type: bytearray".to_owned()))
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyByteArrayIterator {
fn iter(zelf: PyRef<Self>) -> PyByteArrayIterator {
PyByteArrayIterator {
position: Cell::new(0),
bytearray: zelf,
@@ -190,67 +190,67 @@ impl PyByteArray {
}
#[pymethod(name = "isalnum")]
fn isalnum(&self, _vm: &VirtualMachine) -> bool {
fn isalnum(&self) -> bool {
self.inner.borrow().isalnum()
}
#[pymethod(name = "isalpha")]
fn isalpha(&self, _vm: &VirtualMachine) -> bool {
fn isalpha(&self) -> bool {
self.inner.borrow().isalpha()
}
#[pymethod(name = "isascii")]
fn isascii(&self, _vm: &VirtualMachine) -> bool {
fn isascii(&self) -> bool {
self.inner.borrow().isascii()
}
#[pymethod(name = "isdigit")]
fn isdigit(&self, _vm: &VirtualMachine) -> bool {
fn isdigit(&self) -> bool {
self.inner.borrow().isdigit()
}
#[pymethod(name = "islower")]
fn islower(&self, _vm: &VirtualMachine) -> bool {
fn islower(&self) -> bool {
self.inner.borrow().islower()
}
#[pymethod(name = "isspace")]
fn isspace(&self, _vm: &VirtualMachine) -> bool {
fn isspace(&self) -> bool {
self.inner.borrow().isspace()
}
#[pymethod(name = "isupper")]
fn isupper(&self, _vm: &VirtualMachine) -> bool {
fn isupper(&self) -> bool {
self.inner.borrow().isupper()
}
#[pymethod(name = "istitle")]
fn istitle(&self, _vm: &VirtualMachine) -> bool {
fn istitle(&self) -> bool {
self.inner.borrow().istitle()
}
#[pymethod(name = "lower")]
fn lower(&self, _vm: &VirtualMachine) -> PyByteArray {
fn lower(&self) -> PyByteArray {
self.inner.borrow().lower().into()
}
#[pymethod(name = "upper")]
fn upper(&self, _vm: &VirtualMachine) -> PyByteArray {
fn upper(&self) -> PyByteArray {
self.inner.borrow().upper().into()
}
#[pymethod(name = "capitalize")]
fn capitalize(&self, _vm: &VirtualMachine) -> PyByteArray {
fn capitalize(&self) -> PyByteArray {
self.inner.borrow().capitalize().into()
}
#[pymethod(name = "swapcase")]
fn swapcase(&self, _vm: &VirtualMachine) -> PyByteArray {
fn swapcase(&self) -> PyByteArray {
self.inner.borrow().swapcase().into()
}
#[pymethod(name = "hex")]
fn hex(&self, _vm: &VirtualMachine) -> String {
fn hex(&self) -> String {
self.inner.borrow().hex()
}
@@ -331,7 +331,7 @@ impl PyByteArray {
fn index(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult<isize> {
let res = self.inner.borrow().find(options, false, vm)?;
if res == -1 {
return Err(vm.new_value_error("substring not found".to_string()));
return Err(vm.new_value_error("substring not found".to_owned()));
}
Ok(res)
}
@@ -345,7 +345,7 @@ impl PyByteArray {
fn rindex(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult<isize> {
let res = self.inner.borrow().find(options, true, vm)?;
if res == -1 {
return Err(vm.new_value_error("substring not found".to_string()));
return Err(vm.new_value_error("substring not found".to_owned()));
}
Ok(res)
}
@@ -358,7 +358,7 @@ impl PyByteArray {
let pos = bytes
.iter()
.position(|b| *b == x)
.ok_or_else(|| vm.new_value_error("value not found in bytearray".to_string()))?;
.ok_or_else(|| vm.new_value_error("value not found in bytearray".to_owned()))?;
bytes.remove(pos);
@@ -375,11 +375,7 @@ impl PyByteArray {
}
#[pymethod(name = "strip")]
fn strip(
&self,
chars: OptionalArg<PyByteInner>,
_vm: &VirtualMachine,
) -> PyResult<PyByteArray> {
fn strip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyByteArray> {
Ok(self
.inner
.borrow()
@@ -388,11 +384,7 @@ impl PyByteArray {
}
#[pymethod(name = "lstrip")]
fn lstrip(
&self,
chars: OptionalArg<PyByteInner>,
_vm: &VirtualMachine,
) -> PyResult<PyByteArray> {
fn lstrip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyByteArray> {
Ok(self
.inner
.borrow()
@@ -401,11 +393,7 @@ impl PyByteArray {
}
#[pymethod(name = "rstrip")]
fn rstrip(
&self,
chars: OptionalArg<PyByteInner>,
_vm: &VirtualMachine,
) -> PyResult<PyByteArray> {
fn rstrip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyByteArray> {
Ok(self
.inner
.borrow()
@@ -460,7 +448,7 @@ impl PyByteArray {
}
#[pymethod(name = "expandtabs")]
fn expandtabs(&self, options: ByteInnerExpandtabsOptions, _vm: &VirtualMachine) -> PyByteArray {
fn expandtabs(&self, options: ByteInnerExpandtabsOptions) -> PyByteArray {
self.inner.borrow().expandtabs(options).into()
}
@@ -477,7 +465,7 @@ impl PyByteArray {
}
#[pymethod(name = "zfill")]
fn zfill(&self, width: PyIntRef, _vm: &VirtualMachine) -> PyByteArray {
fn zfill(&self, width: PyIntRef) -> PyByteArray {
self.inner.borrow().zfill(width).into()
}
@@ -487,18 +475,17 @@ impl PyByteArray {
old: PyByteInner,
new: PyByteInner,
count: OptionalArg<PyIntRef>,
_vm: &VirtualMachine,
) -> PyResult<PyByteArray> {
Ok(self.inner.borrow().replace(old, new, count)?.into())
}
#[pymethod(name = "clear")]
fn clear(&self, _vm: &VirtualMachine) {
fn clear(&self) {
self.inner.borrow_mut().elements.clear();
}
#[pymethod(name = "copy")]
fn copy(&self, _vm: &VirtualMachine) -> PyByteArray {
fn copy(&self) -> PyByteArray {
self.inner.borrow().elements.clone().into()
}
@@ -529,7 +516,7 @@ impl PyByteArray {
fn insert(&self, mut index: isize, x: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
let bytes = &mut self.inner.borrow_mut().elements;
let len = isize::try_from(bytes.len())
.map_err(|_e| vm.new_overflow_error("bytearray too big".to_string()))?;
.map_err(|_e| vm.new_overflow_error("bytearray too big".to_owned()))?;
let x = x.as_bigint().byte_or(vm)?;
@@ -544,7 +531,7 @@ impl PyByteArray {
}
let index = usize::try_from(index)
.map_err(|_e| vm.new_overflow_error("overflow in index calculation".to_string()))?;
.map_err(|_e| vm.new_overflow_error("overflow in index calculation".to_owned()))?;
bytes.insert(index, x);
@@ -556,26 +543,26 @@ impl PyByteArray {
let bytes = &mut self.inner.borrow_mut().elements;
bytes
.pop()
.ok_or_else(|| vm.new_index_error("pop from empty bytearray".to_string()))
.ok_or_else(|| vm.new_index_error("pop from empty bytearray".to_owned()))
}
#[pymethod(name = "title")]
fn title(&self, _vm: &VirtualMachine) -> PyByteArray {
fn title(&self) -> PyByteArray {
self.inner.borrow().title().into()
}
#[pymethod(name = "__mul__")]
fn repeat(&self, n: isize, _vm: &VirtualMachine) -> PyByteArray {
fn repeat(&self, n: isize) -> PyByteArray {
self.inner.borrow().repeat(n).into()
}
#[pymethod(name = "__rmul__")]
fn rmul(&self, n: isize, vm: &VirtualMachine) -> PyByteArray {
self.repeat(n, vm)
fn rmul(&self, n: isize) -> PyByteArray {
self.repeat(n)
}
#[pymethod(name = "__imul__")]
fn irepeat(&self, n: isize, _vm: &VirtualMachine) {
fn irepeat(&self, n: isize) {
self.inner.borrow_mut().irepeat(n)
}
@@ -603,7 +590,7 @@ impl PyByteArray {
}
#[pymethod(name = "reverse")]
fn reverse(&self, _vm: &VirtualMachine) -> PyResult<()> {
fn reverse(&self) -> PyResult<()> {
self.inner.borrow_mut().elements.reverse();
Ok(())
}
@@ -640,7 +627,7 @@ impl PyByteArrayIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -67,10 +67,10 @@ impl ByteInnerNewOptions {
elements: bytes.get_value().to_vec(),
})
} else {
Err(vm.new_type_error("encoding without a string argument".to_string()))
Err(vm.new_type_error("encoding without a string argument".to_owned()))
}
} else {
Err(vm.new_type_error("encoding without a string argument".to_string()))
Err(vm.new_type_error("encoding without a string argument".to_owned()))
}
// Only one argument
} else {
@@ -79,12 +79,12 @@ impl ByteInnerNewOptions {
i @ PyInt => {
let size = objint::get_value(&i.into_object())
.to_usize()
.ok_or_else(|| vm.new_value_error("negative count".to_string()))?;
.ok_or_else(|| vm.new_value_error("negative count".to_owned()))?;
Ok(vec![0; size])
}
_l @ PyString => {
return Err(
vm.new_type_error("string argument without an encoding".to_string())
vm.new_type_error("string argument without an encoding".to_owned())
);
}
i @ PyBytes => Ok(i.get_value().to_vec()),
@@ -108,9 +108,9 @@ impl ByteInnerNewOptions {
if let Some(i) = v.to_u8() {
data_bytes.push(i);
} else {
return Err(vm.new_value_error(
"bytes must be in range(0, 256)".to_string(),
));
return Err(
vm.new_value_error("bytes must be in range(0, 256)".to_owned())
);
}
}
Ok(data_bytes)
@@ -230,7 +230,7 @@ impl ByteInnerTranslateOptions {
if table.len() != 256 {
return Err(
vm.new_value_error("translation table must be 256 characters long".to_string())
vm.new_value_error("translation table must be 256 characters long".to_owned())
);
}
@@ -395,7 +395,7 @@ impl PyByteInner {
if let Some(idx) = self.elements.get_pos(int) {
Ok(vm.new_int(self.elements[idx]))
} else {
Err(vm.new_index_error("index out of range".to_string()))
Err(vm.new_index_error("index out of range".to_owned()))
}
}
Either::B(slice) => Ok(vm
@@ -411,16 +411,16 @@ impl PyByteInner {
if let Some(value) = i.as_bigint().to_u8() {
Ok(value)
} else {
Err(vm.new_value_error("byte must be in range(0, 256)".to_string()))
Err(vm.new_value_error("byte must be in range(0, 256)".to_owned()))
}
}
_ => Err(vm.new_type_error("an integer is required".to_string())),
_ => Err(vm.new_type_error("an integer is required".to_owned())),
});
let value = result?;
self.elements[idx] = value;
Ok(vm.new_int(value))
} else {
Err(vm.new_index_error("index out of range".to_string()))
Err(vm.new_index_error("index out of range".to_owned()))
}
}
@@ -442,7 +442,7 @@ impl PyByteInner {
i @ PyMemoryView => Ok(i.try_value().unwrap()),
_ => Err(vm.new_index_error(
"can assign only bytes, buffers, or iterables of ints in range(0, 256)"
.to_string()
.to_owned()
)),
}),
};
@@ -479,7 +479,7 @@ impl PyByteInner {
self.elements.remove(idx);
Ok(())
} else {
Err(vm.new_index_error("index out of range".to_string()))
Err(vm.new_index_error("index out of range".to_owned()))
}
}
Either::B(slice) => self.delslice(slice, vm),
@@ -493,7 +493,7 @@ impl PyByteInner {
let step = slice.step_index(vm)?.unwrap_or_else(BigInt::one);
if step.is_zero() {
Err(vm.new_value_error("slice step cannot be zero".to_string()))
Err(vm.new_value_error("slice step cannot be zero".to_owned()))
} else if step.is_positive() {
let range = self.elements.get_slice_range(&start, &stop);
if range.start < range.end {
@@ -1215,7 +1215,7 @@ pub trait ByteOr: ToPrimitive {
fn byte_or(&self, vm: &VirtualMachine) -> PyResult<u8> {
match self.to_u8() {
Some(value) => Ok(value),
None => Err(vm.new_value_error("byte must be in range(0, 256)".to_string())),
None => Err(vm.new_value_error("byte must be in range(0, 256)".to_owned())),
}
}
}

View File

@@ -109,7 +109,7 @@ impl PyBytes {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.inner.len()
}
@@ -135,12 +135,12 @@ impl PyBytes {
}
#[pymethod(name = "__hash__")]
fn hash(&self, _vm: &VirtualMachine) -> pyhash::PyHash {
fn hash(&self) -> pyhash::PyHash {
self.inner.hash()
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyBytesIterator {
fn iter(zelf: PyRef<Self>) -> PyBytesIterator {
PyBytesIterator {
position: Cell::new(0),
bytes: zelf,
@@ -148,7 +148,7 @@ impl PyBytes {
}
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> PyResult<usize> {
fn sizeof(&self) -> PyResult<usize> {
Ok(size_of::<Self>() + self.inner.elements.len() * size_of::<u8>())
}
@@ -176,67 +176,67 @@ impl PyBytes {
}
#[pymethod(name = "isalnum")]
fn isalnum(&self, _vm: &VirtualMachine) -> bool {
fn isalnum(&self) -> bool {
self.inner.isalnum()
}
#[pymethod(name = "isalpha")]
fn isalpha(&self, _vm: &VirtualMachine) -> bool {
fn isalpha(&self) -> bool {
self.inner.isalpha()
}
#[pymethod(name = "isascii")]
fn isascii(&self, _vm: &VirtualMachine) -> bool {
fn isascii(&self) -> bool {
self.inner.isascii()
}
#[pymethod(name = "isdigit")]
fn isdigit(&self, _vm: &VirtualMachine) -> bool {
fn isdigit(&self) -> bool {
self.inner.isdigit()
}
#[pymethod(name = "islower")]
fn islower(&self, _vm: &VirtualMachine) -> bool {
fn islower(&self) -> bool {
self.inner.islower()
}
#[pymethod(name = "isspace")]
fn isspace(&self, _vm: &VirtualMachine) -> bool {
fn isspace(&self) -> bool {
self.inner.isspace()
}
#[pymethod(name = "isupper")]
fn isupper(&self, _vm: &VirtualMachine) -> bool {
fn isupper(&self) -> bool {
self.inner.isupper()
}
#[pymethod(name = "istitle")]
fn istitle(&self, _vm: &VirtualMachine) -> bool {
fn istitle(&self) -> bool {
self.inner.istitle()
}
#[pymethod(name = "lower")]
fn lower(&self, _vm: &VirtualMachine) -> PyBytes {
fn lower(&self) -> PyBytes {
self.inner.lower().into()
}
#[pymethod(name = "upper")]
fn upper(&self, _vm: &VirtualMachine) -> PyBytes {
fn upper(&self) -> PyBytes {
self.inner.upper().into()
}
#[pymethod(name = "capitalize")]
fn capitalize(&self, _vm: &VirtualMachine) -> PyBytes {
fn capitalize(&self) -> PyBytes {
self.inner.capitalize().into()
}
#[pymethod(name = "swapcase")]
fn swapcase(&self, _vm: &VirtualMachine) -> PyBytes {
fn swapcase(&self) -> PyBytes {
self.inner.swapcase().into()
}
#[pymethod(name = "hex")]
fn hex(&self, _vm: &VirtualMachine) -> String {
fn hex(&self) -> String {
self.inner.hex()
}
@@ -301,7 +301,7 @@ impl PyBytes {
fn index(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult<isize> {
let res = self.inner.find(options, false, vm)?;
if res == -1 {
return Err(vm.new_value_error("substring not found".to_string()));
return Err(vm.new_value_error("substring not found".to_owned()));
}
Ok(res)
}
@@ -315,7 +315,7 @@ impl PyBytes {
fn rindex(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult<isize> {
let res = self.inner.find(options, true, vm)?;
if res == -1 {
return Err(vm.new_value_error("substring not found".to_string()));
return Err(vm.new_value_error("substring not found".to_owned()));
}
Ok(res)
}
@@ -330,17 +330,17 @@ impl PyBytes {
}
#[pymethod(name = "strip")]
fn strip(&self, chars: OptionalArg<PyByteInner>, _vm: &VirtualMachine) -> PyResult<PyBytes> {
fn strip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyBytes> {
Ok(self.inner.strip(chars, ByteInnerPosition::All)?.into())
}
#[pymethod(name = "lstrip")]
fn lstrip(&self, chars: OptionalArg<PyByteInner>, _vm: &VirtualMachine) -> PyResult<PyBytes> {
fn lstrip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyBytes> {
Ok(self.inner.strip(chars, ByteInnerPosition::Left)?.into())
}
#[pymethod(name = "rstrip")]
fn rstrip(&self, chars: OptionalArg<PyByteInner>, _vm: &VirtualMachine) -> PyResult<PyBytes> {
fn rstrip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyBytes> {
Ok(self.inner.strip(chars, ByteInnerPosition::Right)?.into())
}
@@ -386,7 +386,7 @@ impl PyBytes {
}
#[pymethod(name = "expandtabs")]
fn expandtabs(&self, options: ByteInnerExpandtabsOptions, _vm: &VirtualMachine) -> PyBytes {
fn expandtabs(&self, options: ByteInnerExpandtabsOptions) -> PyBytes {
self.inner.expandtabs(options).into()
}
@@ -402,7 +402,7 @@ impl PyBytes {
}
#[pymethod(name = "zfill")]
fn zfill(&self, width: PyIntRef, _vm: &VirtualMachine) -> PyBytes {
fn zfill(&self, width: PyIntRef) -> PyBytes {
self.inner.zfill(width).into()
}
@@ -412,24 +412,23 @@ impl PyBytes {
old: PyByteInner,
new: PyByteInner,
count: OptionalArg<PyIntRef>,
_vm: &VirtualMachine,
) -> PyResult<PyBytes> {
Ok(self.inner.replace(old, new, count)?.into())
}
#[pymethod(name = "title")]
fn title(&self, _vm: &VirtualMachine) -> PyBytes {
fn title(&self) -> PyBytes {
self.inner.title().into()
}
#[pymethod(name = "__mul__")]
fn repeat(&self, n: isize, _vm: &VirtualMachine) -> PyBytes {
fn repeat(&self, n: isize) -> PyBytes {
self.inner.repeat(n).into()
}
#[pymethod(name = "__rmul__")]
fn rmul(&self, n: isize, vm: &VirtualMachine) -> PyBytes {
self.repeat(n, vm)
fn rmul(&self, n: isize) -> PyBytes {
self.repeat(n)
}
fn do_cformat(
@@ -512,7 +511,7 @@ impl PyBytesIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -3,7 +3,7 @@ use crate::function::OptionalArg;
use crate::pyobject::{
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::slots::PyBuiltinDescriptor;
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;
/// classmethod(function) -> method
@@ -47,19 +47,20 @@ impl PyValue for PyClassMethod {
}
}
impl PyBuiltinDescriptor for PyClassMethod {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyClassMethod {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
let cls = cls.unwrap_or_else(|| obj.class().into_object());
Ok(vm.ctx.new_bound_method(zelf.callable.clone(), cls))
}
}
#[pyimpl(with(PyBuiltinDescriptor), flags(BASETYPE))]
#[pyimpl(with(SlotDescriptor), flags(BASETYPE))]
impl PyClassMethod {
#[pyslot]
fn tp_new(
@@ -74,7 +75,7 @@ impl PyClassMethod {
}
#[pyproperty(name = "__func__")]
fn func(&self, _vm: &VirtualMachine) -> PyObjectRef {
fn func(&self) -> PyObjectRef {
self.callable.clone()
}
}

View File

@@ -44,10 +44,10 @@ impl PyValue for PyCode {
impl PyCodeRef {
#[allow(clippy::new_ret_no_self)]
fn new(_cls: PyClassRef, vm: &VirtualMachine) -> PyResult {
Err(vm.new_type_error("Cannot directly create code object".to_string()))
Err(vm.new_type_error("Cannot directly create code object".to_owned()))
}
fn repr(self, _vm: &VirtualMachine) -> String {
fn repr(self) -> String {
let code = &self.code;
format!(
"<code object {} at 0x{:x} file {:?}, line {}>",
@@ -58,19 +58,19 @@ impl PyCodeRef {
)
}
fn co_argcount(self, _vm: &VirtualMachine) -> usize {
fn co_argcount(self) -> usize {
self.code.arg_names.len()
}
fn co_filename(self, _vm: &VirtualMachine) -> String {
fn co_filename(self) -> String {
self.code.source_path.clone()
}
fn co_firstlineno(self, _vm: &VirtualMachine) -> usize {
fn co_firstlineno(self) -> usize {
self.code.first_line_number
}
fn co_kwonlyargcount(self, _vm: &VirtualMachine) -> usize {
fn co_kwonlyargcount(self) -> usize {
self.code.kwonlyarg_names.len()
}
@@ -83,26 +83,26 @@ impl PyCodeRef {
vm.ctx.new_tuple(consts)
}
fn co_name(self, _vm: &VirtualMachine) -> String {
fn co_name(self) -> String {
self.code.obj_name.clone()
}
fn co_flags(self, _vm: &VirtualMachine) -> u8 {
fn co_flags(self) -> u8 {
self.code.flags.bits()
}
}
pub fn init(context: &PyContext) {
extend_class!(context, &context.types.code_type, {
pub fn init(ctx: &PyContext) {
extend_class!(ctx, &ctx.types.code_type, {
(slot new) => PyCodeRef::new,
"__repr__" => context.new_method(PyCodeRef::repr),
"__repr__" => ctx.new_method(PyCodeRef::repr),
"co_argcount" => context.new_property(PyCodeRef::co_argcount),
"co_consts" => context.new_property(PyCodeRef::co_consts),
"co_filename" => context.new_property(PyCodeRef::co_filename),
"co_firstlineno" => context.new_property(PyCodeRef::co_firstlineno),
"co_kwonlyargcount" => context.new_property(PyCodeRef::co_kwonlyargcount),
"co_name" => context.new_property(PyCodeRef::co_name),
"co_flags" => context.new_property(PyCodeRef::co_flags),
"co_argcount" => ctx.new_readonly_getset("co_argcount", PyCodeRef::co_argcount),
"co_consts" => ctx.new_readonly_getset("co_consts", PyCodeRef::co_consts),
"co_filename" => ctx.new_readonly_getset("co_filename", PyCodeRef::co_filename),
"co_firstlineno" => ctx.new_readonly_getset("co_firstlineno", PyCodeRef::co_firstlineno),
"co_kwonlyargcount" => ctx.new_readonly_getset("co_kwonlyargcount", PyCodeRef::co_kwonlyargcount),
"co_name" => ctx.new_readonly_getset("co_name", PyCodeRef::co_name),
"co_flags" => ctx.new_readonly_getset("co_flags", PyCodeRef::co_flags),
});
}

View File

@@ -57,17 +57,17 @@ fn try_complex(value: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<Comp
#[pyimpl(flags(BASETYPE))]
impl PyComplex {
#[pyproperty(name = "real")]
fn real(&self, _vm: &VirtualMachine) -> f64 {
fn real(&self) -> f64 {
self.value.re
}
#[pyproperty(name = "imag")]
fn imag(&self, _vm: &VirtualMachine) -> f64 {
fn imag(&self) -> f64 {
self.value.im
}
#[pymethod(name = "__abs__")]
fn abs(&self, _vm: &VirtualMachine) -> f64 {
fn abs(&self) -> f64 {
let Complex64 { im, re } = self.value;
re.hypot(im)
}
@@ -104,7 +104,7 @@ impl PyComplex {
}
#[pymethod(name = "conjugate")]
fn conjugate(&self, _vm: &VirtualMachine) -> Complex64 {
fn conjugate(&self) -> Complex64 {
self.value.conj()
}
@@ -155,7 +155,7 @@ impl PyComplex {
#[pymethod(name = "__mod__")]
fn mod_(&self, _other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Err(vm.new_type_error("can't mod complex numbers.".to_string()))
Err(vm.new_type_error("can't mod complex numbers.".to_owned()))
}
#[pymethod(name = "__rmod__")]
@@ -165,7 +165,7 @@ impl PyComplex {
#[pymethod(name = "__floordiv__")]
fn floordiv(&self, _other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Err(vm.new_type_error("can't take floor of complex number.".to_string()))
Err(vm.new_type_error("can't take floor of complex number.".to_owned()))
}
#[pymethod(name = "__rfloordiv__")]
@@ -175,7 +175,7 @@ impl PyComplex {
#[pymethod(name = "__divmod__")]
fn divmod(&self, _other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Err(vm.new_type_error("can't take floor or mod of complex number.".to_string()))
Err(vm.new_type_error("can't take floor or mod of complex number.".to_owned()))
}
#[pymethod(name = "__rdivmod__")]
@@ -184,12 +184,12 @@ impl PyComplex {
}
#[pymethod(name = "__neg__")]
fn neg(&self, _vm: &VirtualMachine) -> Complex64 {
fn neg(&self) -> Complex64 {
-self.value
}
#[pymethod(name = "__repr__")]
fn repr(&self, _vm: &VirtualMachine) -> String {
fn repr(&self) -> String {
let Complex64 { re, im } = self.value;
if re == 0.0 {
format!("{}j", im)
@@ -209,7 +209,7 @@ impl PyComplex {
}
#[pymethod(name = "__bool__")]
fn bool(&self, _vm: &VirtualMachine) -> bool {
fn bool(&self) -> bool {
!Complex64::is_zero(&self.value)
}
@@ -235,7 +235,7 @@ impl PyComplex {
}
#[pymethod(name = "__hash__")]
fn hash(&self, _vm: &VirtualMachine) -> pyhash::PyHash {
fn hash(&self) -> pyhash::PyHash {
let re_hash = pyhash::hash_float(self.value.re);
let im_hash = pyhash::hash_float(self.value.im);
let ret = Wrapping(re_hash) + Wrapping(im_hash) * Wrapping(pyhash::IMAG);

View File

@@ -91,7 +91,7 @@ impl PyCoroutine {
match result {
Ok(ExecutionResult::Yield(_)) => Err(vm.new_exception_msg(
vm.ctx.exceptions.runtime_error.clone(),
"generator ignored GeneratorExit".to_string(),
"generator ignored GeneratorExit".to_owned(),
)),
Err(e) => {
if isinstance(&e, &vm.ctx.exceptions.generator_exit) {
@@ -105,7 +105,7 @@ impl PyCoroutine {
}
#[pymethod(name = "__await__")]
fn r#await(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyCoroutineWrapper {
fn r#await(zelf: PyRef<Self>) -> PyCoroutineWrapper {
PyCoroutineWrapper { coro: zelf }
}
}
@@ -125,7 +125,7 @@ impl PyValue for PyCoroutineWrapper {
#[pyimpl]
impl PyCoroutineWrapper {
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}

View File

@@ -79,7 +79,7 @@ impl PyDictRef {
let iter = objiter::get_iter(vm, &dict_obj)?;
loop {
fn err(vm: &VirtualMachine) -> PyBaseExceptionRef {
vm.new_type_error("Iterator must have exactly two elements".to_string())
vm.new_type_error("Iterator must have exactly two elements".to_owned())
}
let element = match objiter::get_next_object(vm, &iter)? {
Some(obj) => obj,
@@ -121,7 +121,7 @@ impl PyDictRef {
}
#[pymethod(magic)]
fn bool(self, _vm: &VirtualMachine) -> bool {
fn bool(self) -> bool {
!self.entries.borrow().is_empty()
}
@@ -168,12 +168,12 @@ impl PyDictRef {
}
#[pymethod(magic)]
fn len(self, _vm: &VirtualMachine) -> usize {
fn len(self) -> usize {
self.entries.borrow().len()
}
#[pymethod(magic)]
fn sizeof(self, _vm: &VirtualMachine) -> usize {
fn sizeof(self) -> usize {
size_of::<Self>() + self.entries.borrow().sizeof()
}
@@ -189,7 +189,7 @@ impl PyDictRef {
format!("{{{}}}", str_parts.join(", "))
} else {
"{...}".to_string()
"{...}".to_owned()
};
Ok(s)
}
@@ -205,27 +205,27 @@ impl PyDictRef {
}
#[pymethod]
fn clear(self, _vm: &VirtualMachine) {
fn clear(self) {
self.entries.borrow_mut().clear()
}
#[pymethod(magic)]
fn iter(self, _vm: &VirtualMachine) -> PyDictKeyIterator {
fn iter(self) -> PyDictKeyIterator {
PyDictKeyIterator::new(self)
}
#[pymethod]
fn keys(self, _vm: &VirtualMachine) -> PyDictKeys {
fn keys(self) -> PyDictKeys {
PyDictKeys::new(self)
}
#[pymethod]
fn values(self, _vm: &VirtualMachine) -> PyDictValues {
fn values(self) -> PyDictValues {
PyDictValues::new(self)
}
#[pymethod]
fn items(self, _vm: &VirtualMachine) -> PyDictItems {
fn items(self) -> PyDictItems {
PyDictItems::new(self)
}
@@ -305,7 +305,7 @@ impl PyDictRef {
}
#[pymethod]
pub fn copy(self, _vm: &VirtualMachine) -> PyDict {
pub fn copy(self) -> PyDict {
PyDict {
entries: self.entries.clone(),
}
@@ -343,7 +343,7 @@ impl PyDictRef {
if let Some((key, value)) = entries.pop_front() {
Ok(vm.ctx.new_tuple(vec![key, value]))
} else {
let err_msg = vm.new_str("popitem(): dictionary is empty".to_string());
let err_msg = vm.new_str("popitem(): dictionary is empty".to_owned());
Err(vm.new_key_error(err_msg))
}
}
@@ -371,7 +371,7 @@ impl PyDictRef {
#[pymethod(magic)]
fn hash(self, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_type_error("unhashable type".to_string()))
Err(vm.new_type_error("unhashable type".to_owned()))
}
pub fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool {
@@ -508,13 +508,13 @@ macro_rules! dict_iterator {
}
#[pymethod(name = "__iter__")]
fn iter(&self, _vm: &VirtualMachine) -> $iter_name {
fn iter(&self) -> $iter_name {
$iter_name::new(self.dict.clone())
}
#[pymethod(name = "__len__")]
fn len(&self, vm: &VirtualMachine) -> usize {
self.dict.clone().len(vm)
fn len(&self) -> usize {
self.dict.clone().len()
}
#[pymethod(name = "__repr__")]
@@ -524,11 +524,11 @@ macro_rules! dict_iterator {
let mut str_parts = vec![];
for (key, value) in zelf.dict.clone() {
let s = vm.to_repr(&$result_fn(vm, &key, &value))?;
str_parts.push(s.as_str().to_string());
str_parts.push(s.as_str().to_owned());
}
format!("{}([{}])", $class_name, str_parts.join(", "))
} else {
"{...}".to_string()
"{...}".to_owned()
};
Ok(s)
}
@@ -566,7 +566,7 @@ macro_rules! dict_iterator {
if dict.has_changed_size(&self.size) {
return Err(vm.new_exception_msg(
vm.ctx.exceptions.runtime_error.clone(),
"dictionary changed size during iteration".to_string(),
"dictionary changed size during iteration".to_owned(),
));
}
match dict.next_entry(&mut position) {
@@ -579,12 +579,12 @@ macro_rules! dict_iterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
#[pymethod(name = "__length_hint__")]
fn length_hint(&self, _vm: &VirtualMachine) -> usize {
fn length_hint(&self) -> usize {
self.dict
.entries
.borrow()

View File

@@ -21,10 +21,10 @@ fn ellipsis_new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult {
}
}
fn ellipsis_repr(_self: PyEllipsisRef, _vm: &VirtualMachine) -> String {
"Ellipsis".to_string()
fn ellipsis_repr(_self: PyEllipsisRef) -> String {
"Ellipsis".to_owned()
}
fn ellipsis_reduce(_self: PyEllipsisRef, _vm: &VirtualMachine) -> String {
"Ellipsis".to_string()
fn ellipsis_reduce(_self: PyEllipsisRef) -> String {
"Ellipsis".to_owned()
}

View File

@@ -62,7 +62,7 @@ impl PyEnumerate {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -61,7 +61,7 @@ impl PyFilter {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -80,7 +80,7 @@ fn inner_div(v1: f64, v2: f64, vm: &VirtualMachine) -> PyResult<f64> {
if v2 != 0.0 {
Ok(v1 / v2)
} else {
Err(vm.new_zero_division_error("float division by zero".to_string()))
Err(vm.new_zero_division_error("float division by zero".to_owned()))
}
}
@@ -88,7 +88,7 @@ fn inner_mod(v1: f64, v2: f64, vm: &VirtualMachine) -> PyResult<f64> {
if v2 != 0.0 {
Ok(v1 % v2)
} else {
Err(vm.new_zero_division_error("float mod by zero".to_string()))
Err(vm.new_zero_division_error("float mod by zero".to_owned()))
}
}
@@ -98,11 +98,11 @@ pub fn try_bigint(value: f64, vm: &VirtualMachine) -> PyResult<BigInt> {
None => {
if value.is_infinite() {
Err(vm.new_overflow_error(
"OverflowError: cannot convert float infinity to integer".to_string(),
"OverflowError: cannot convert float infinity to integer".to_owned(),
))
} else if value.is_nan() {
Err(vm
.new_value_error("ValueError: cannot convert float NaN to integer".to_string()))
.new_value_error("ValueError: cannot convert float NaN to integer".to_owned()))
} else {
// unreachable unless BigInt has a bug
unreachable!(
@@ -118,7 +118,7 @@ fn inner_floordiv(v1: f64, v2: f64, vm: &VirtualMachine) -> PyResult<f64> {
if v2 != 0.0 {
Ok((v1 / v2).floor())
} else {
Err(vm.new_zero_division_error("float floordiv by zero".to_string()))
Err(vm.new_zero_division_error("float floordiv by zero".to_owned()))
}
}
@@ -126,7 +126,7 @@ fn inner_divmod(v1: f64, v2: f64, vm: &VirtualMachine) -> PyResult<(f64, f64)> {
if v2 != 0.0 {
Ok(((v1 / v2).floor(), v1 % v2))
} else {
Err(vm.new_zero_division_error("float divmod()".to_string()))
Err(vm.new_zero_division_error("float divmod()".to_owned()))
}
}
@@ -273,7 +273,7 @@ impl PyFloat {
}
#[pymethod(name = "__abs__")]
fn abs(&self, _vm: &VirtualMachine) -> f64 {
fn abs(&self) -> f64 {
self.value.abs()
}
@@ -315,7 +315,7 @@ impl PyFloat {
}
#[pymethod(name = "__bool__")]
fn bool(&self, _vm: &VirtualMachine) -> bool {
fn bool(&self) -> bool {
self.value != 0.0
}
@@ -350,12 +350,12 @@ impl PyFloat {
}
#[pymethod(name = "__pos__")]
fn pos(&self, _vm: &VirtualMachine) -> f64 {
fn pos(&self) -> f64 {
self.value
}
#[pymethod(name = "__neg__")]
fn neg(&self, _vm: &VirtualMachine) -> f64 {
fn neg(&self) -> f64 {
-self.value
}
@@ -380,14 +380,14 @@ impl PyFloat {
}
#[pymethod(name = "__repr__")]
fn repr(&self, vm: &VirtualMachine) -> String {
fn repr(&self) -> String {
let value = format!("{:e}", self.value);
if let Some(position) = value.find('e') {
let significand = &value[..position];
let exponent = &value[position + 1..];
let exponent = exponent.parse::<i32>().unwrap();
if exponent < 16 && exponent > -5 {
if self.is_integer(vm) {
if self.is_integer() {
format!("{:.1?}", self.value)
} else {
self.value.to_string()
@@ -489,32 +489,32 @@ impl PyFloat {
}
#[pymethod(name = "__float__")]
fn float(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyFloatRef {
fn float(zelf: PyRef<Self>) -> PyFloatRef {
zelf
}
#[pymethod(name = "__hash__")]
fn hash(&self, _vm: &VirtualMachine) -> pyhash::PyHash {
fn hash(&self) -> pyhash::PyHash {
pyhash::hash_float(self.value)
}
#[pyproperty(name = "real")]
fn real(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyFloatRef {
#[pyproperty]
fn real(zelf: PyRef<Self>) -> PyFloatRef {
zelf
}
#[pyproperty(name = "imag")]
fn imag(&self, _vm: &VirtualMachine) -> f64 {
#[pyproperty]
fn imag(&self) -> f64 {
0.0f64
}
#[pymethod(name = "conjugate")]
fn conjugate(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyFloatRef {
fn conjugate(zelf: PyRef<Self>) -> PyFloatRef {
zelf
}
#[pymethod(name = "is_integer")]
fn is_integer(&self, _vm: &VirtualMachine) -> bool {
fn is_integer(&self) -> bool {
let v = self.value;
(v - v.round()).abs() < std::f64::EPSILON
}
@@ -524,11 +524,11 @@ impl PyFloat {
let value = self.value;
if value.is_infinite() {
return Err(
vm.new_overflow_error("cannot convert Infinity to integer ratio".to_string())
vm.new_overflow_error("cannot convert Infinity to integer ratio".to_owned())
);
}
if value.is_nan() {
return Err(vm.new_value_error("cannot convert NaN to integer ratio".to_string()));
return Err(vm.new_value_error("cannot convert NaN to integer ratio".to_owned()));
}
let ratio = Ratio::from_float(value).unwrap();
@@ -584,7 +584,7 @@ impl PyFloat {
}
hexf_parse::parse_hexf64(hex.as_str(), false).map_err(|_| {
vm.new_value_error("invalid hexadecimal floating-point string".to_string())
vm.new_value_error("invalid hexadecimal floating-point string".to_owned())
})
}
}
@@ -592,7 +592,7 @@ impl PyFloat {
}
#[pymethod]
fn hex(&self, _vm: &VirtualMachine) -> String {
fn hex(&self) -> String {
to_hex(self.value)
}
}
@@ -661,7 +661,7 @@ fn to_hex(value: f64) -> String {
match value {
value if value.is_zero() => format!("{}0x0.0p+0", sign_fmt),
value if value.is_infinite() => format!("{}inf", sign_fmt),
value if value.is_nan() => "nan".to_string(),
value if value.is_nan() => "nan".to_owned(),
_ => {
const BITS: i16 = 52;
const FRACT_MASK: u64 = 0xf_ffff_ffff_ffff;

View File

@@ -16,31 +16,31 @@ pub fn init(context: &PyContext) {
impl FrameRef {
#[pyslot]
fn tp_new(_cls: FrameRef, vm: &VirtualMachine) -> PyResult<Self> {
Err(vm.new_type_error("Cannot directly create frame object".to_string()))
Err(vm.new_type_error("Cannot directly create frame object".to_owned()))
}
#[pymethod(name = "__repr__")]
fn repr(self, _vm: &VirtualMachine) -> String {
"<frame object at .. >".to_string()
fn repr(self) -> String {
"<frame object at .. >".to_owned()
}
#[pymethod]
fn clear(self, _vm: &VirtualMachine) {
fn clear(self) {
// TODO
}
#[pyproperty]
fn f_globals(self, _vm: &VirtualMachine) -> PyDictRef {
fn f_globals(self) -> PyDictRef {
self.scope.globals.clone()
}
#[pyproperty]
fn f_locals(self, _vm: &VirtualMachine) -> PyDictRef {
fn f_locals(self) -> PyDictRef {
self.scope.get_locals()
}
#[pyproperty]
fn f_code(self, _vm: &VirtualMachine) -> PyCodeRef {
fn f_code(self) -> PyCodeRef {
self.code.clone()
}

View File

@@ -13,7 +13,7 @@ use crate::pyobject::{
TypeProtocol,
};
use crate::scope::Scope;
use crate::slots::{PyBuiltinCallable, PyBuiltinDescriptor};
use crate::slots::{SlotCall, SlotDescriptor};
use crate::vm::VirtualMachine;
pub type PyFunctionRef = PyRef<PyFunction>;
@@ -27,13 +27,14 @@ pub struct PyFunction {
kw_only_defaults: Option<PyDictRef>,
}
impl PyBuiltinDescriptor for PyFunction {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyFunction {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
if obj.is(&vm.get_none()) && !Self::_cls_is(&cls, &obj.class()) {
Ok(zelf.into_object())
} else {
@@ -240,7 +241,7 @@ impl PyValue for PyFunction {
}
}
#[pyimpl(with(PyBuiltinDescriptor))]
#[pyimpl(with(SlotDescriptor))]
impl PyFunction {
#[pyslot]
#[pymethod(magic)]
@@ -248,18 +249,18 @@ impl PyFunction {
self.invoke(args, vm)
}
#[pyproperty(name = "__code__")]
fn code(&self, _vm: &VirtualMachine) -> PyCodeRef {
#[pyproperty(magic)]
fn code(&self) -> PyCodeRef {
self.code.clone()
}
#[pyproperty(name = "__defaults__")]
fn defaults(&self, _vm: &VirtualMachine) -> Option<PyTupleRef> {
#[pyproperty(magic)]
fn defaults(&self) -> Option<PyTupleRef> {
self.defaults.clone()
}
#[pyproperty(name = "__kwdefaults__")]
fn kwdefaults(&self, _vm: &VirtualMachine) -> Option<PyDictRef> {
#[pyproperty(magic)]
fn kwdefaults(&self) -> Option<PyDictRef> {
self.kw_only_defaults.clone()
}
}
@@ -272,7 +273,7 @@ pub struct PyBoundMethod {
pub function: PyObjectRef,
}
impl PyBuiltinCallable for PyBoundMethod {
impl SlotCall for PyBoundMethod {
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
let args = args.insert(self.object.clone());
vm.invoke(&self.function, args)
@@ -285,7 +286,7 @@ impl PyBoundMethod {
}
}
#[pyimpl(with(PyBuiltinCallable))]
#[pyimpl(with(SlotCall))]
impl PyBoundMethod {
#[pymethod(magic)]
fn getattribute(&self, name: PyStringRef, vm: &VirtualMachine) -> PyResult {

View File

@@ -45,7 +45,7 @@ impl PyGenerator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyGeneratorRef, _vm: &VirtualMachine) -> PyGeneratorRef {
fn iter(zelf: PyGeneratorRef) -> PyGeneratorRef {
zelf
}
@@ -104,7 +104,7 @@ impl PyGenerator {
match result {
Ok(ExecutionResult::Yield(_)) => Err(vm.new_exception_msg(
vm.ctx.exceptions.runtime_error.clone(),
"generator ignored GeneratorExit".to_string(),
"generator ignored GeneratorExit".to_owned(),
)),
Err(e) => {
if isinstance(&e, &vm.ctx.exceptions.generator_exit) {

249
vm/src/obj/objgetset.rs Normal file
View File

@@ -0,0 +1,249 @@
/*! Python `attribute` descriptor class. (PyGetSet)
*/
use super::objtype::PyClassRef;
use crate::function::{OptionalArg, OwnedParam, RefParam};
use crate::pyobject::{
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
};
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;
pub type PyGetterFunc = Box<dyn Fn(&VirtualMachine, PyObjectRef) -> PyResult>;
pub type PySetterFunc = Box<dyn Fn(&VirtualMachine, PyObjectRef, PyObjectRef) -> PyResult<()>>;
pub trait IntoPyGetterFunc<T> {
fn into_getter(self) -> PyGetterFunc;
}
impl<F, T, R> IntoPyGetterFunc<(OwnedParam<T>, R, VirtualMachine)> for F
where
F: Fn(T, &VirtualMachine) -> R + 'static,
T: TryFromObject,
R: IntoPyObject,
{
fn into_getter(self) -> PyGetterFunc {
Box::new(move |vm, obj| {
let obj = T::try_from_object(vm, obj)?;
(self)(obj, vm).into_pyobject(vm)
})
}
}
impl<F, S, R> IntoPyGetterFunc<(RefParam<S>, R, VirtualMachine)> for F
where
F: Fn(&S, &VirtualMachine) -> R + 'static,
S: PyValue,
R: IntoPyObject,
{
fn into_getter(self) -> PyGetterFunc {
Box::new(move |vm, obj| {
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
(self)(&zelf, vm).into_pyobject(vm)
})
}
}
impl<F, T, R> IntoPyGetterFunc<(OwnedParam<T>, R)> for F
where
F: Fn(T) -> R + 'static,
T: TryFromObject,
R: IntoPyObject,
{
fn into_getter(self) -> PyGetterFunc {
IntoPyGetterFunc::into_getter(move |obj, _vm: &VirtualMachine| (self)(obj))
}
}
impl<F, S, R> IntoPyGetterFunc<(RefParam<S>, R)> for F
where
F: Fn(&S) -> R + 'static,
S: PyValue,
R: IntoPyObject,
{
fn into_getter(self) -> PyGetterFunc {
IntoPyGetterFunc::into_getter(move |zelf: &S, _vm: &VirtualMachine| (self)(zelf))
}
}
pub trait IntoPyNoResult {
fn into_noresult(self) -> PyResult<()>;
}
impl IntoPyNoResult for () {
fn into_noresult(self) -> PyResult<()> {
Ok(())
}
}
impl IntoPyNoResult for PyResult<()> {
fn into_noresult(self) -> PyResult<()> {
self
}
}
pub trait IntoPySetterFunc<T> {
fn into_setter(self) -> PySetterFunc;
}
impl<F, T, V, R> IntoPySetterFunc<(OwnedParam<T>, V, R, VirtualMachine)> for F
where
F: Fn(T, V, &VirtualMachine) -> R + 'static,
T: TryFromObject,
V: TryFromObject,
R: IntoPyNoResult,
{
fn into_setter(self) -> PySetterFunc {
Box::new(move |vm, obj, value| {
let obj = T::try_from_object(vm, obj)?;
let value = V::try_from_object(vm, value)?;
(self)(obj, value, vm).into_noresult()
})
}
}
impl<F, S, V, R> IntoPySetterFunc<(RefParam<S>, V, R, VirtualMachine)> for F
where
F: Fn(&S, V, &VirtualMachine) -> R + 'static,
S: PyValue,
V: TryFromObject,
R: IntoPyNoResult,
{
fn into_setter(self) -> PySetterFunc {
Box::new(move |vm, obj, value| {
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
let value = V::try_from_object(vm, value)?;
(self)(&zelf, value, vm).into_noresult()
})
}
}
impl<F, T, V, R> IntoPySetterFunc<(OwnedParam<T>, V, R)> for F
where
F: Fn(T, V) -> R + 'static,
T: TryFromObject,
V: TryFromObject,
R: IntoPyNoResult,
{
fn into_setter(self) -> PySetterFunc {
IntoPySetterFunc::into_setter(move |obj, v, _vm: &VirtualMachine| (self)(obj, v))
}
}
impl<F, S, V, R> IntoPySetterFunc<(RefParam<S>, V, R)> for F
where
F: Fn(&S, V) -> R + 'static,
S: PyValue,
V: TryFromObject,
R: IntoPyNoResult,
{
fn into_setter(self) -> PySetterFunc {
IntoPySetterFunc::into_setter(move |zelf: &S, v, _vm: &VirtualMachine| (self)(zelf, v))
}
}
#[pyclass]
pub struct PyGetSet {
name: String,
getter: Option<PyGetterFunc>,
setter: Option<PySetterFunc>,
// doc: Option<String>,
}
impl std::fmt::Debug for PyGetSet {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"PyGetSet {{ name: {}, getter: {}, setter: {} }}",
self.name,
if self.getter.is_some() {
"Some"
} else {
"None"
},
if self.setter.is_some() {
"Some"
} else {
"None"
},
)
}
}
impl PyValue for PyGetSet {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.ctx.getset_type()
}
}
pub type PyGetSetRef = PyRef<PyGetSet>;
impl SlotDescriptor for PyGetSet {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
_cls: OptionalArg<PyObjectRef>,
) -> PyResult {
let (zelf, obj) = match Self::_check(zelf, obj, vm) {
Ok(obj) => obj,
Err(result) => return result,
};
if let Some(ref f) = zelf.getter {
f(vm, obj)
} else {
Err(vm.new_attribute_error(format!(
"attribute '{}' of '{}' objects is not readable",
zelf.name,
Self::class(vm).name
)))
}
}
}
impl PyGetSet {
pub fn with_get<G, X>(name: String, getter: G) -> Self
where
G: IntoPyGetterFunc<X>,
{
Self {
name,
getter: Some(getter.into_getter()),
setter: None,
}
}
pub fn with_get_set<G, S, X, Y>(name: String, getter: G, setter: S) -> Self
where
G: IntoPyGetterFunc<X>,
S: IntoPySetterFunc<Y>,
{
Self {
name,
getter: Some(getter.into_getter()),
setter: Some(setter.into_setter()),
}
}
}
#[pyimpl(with(SlotDescriptor))]
impl PyGetSet {
// Descriptor methods
#[pymethod(magic)]
fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
if let Some(ref f) = self.setter {
f(vm, obj, value)
} else {
Err(vm.new_attribute_error(format!(
"attribute '{}' of '{}' objects is not writable",
self.name,
Self::class(vm).name
)))
}
}
}
pub(crate) fn init(context: &PyContext) {
PyGetSet::extend_class(context, &context.types.getset_type);
}

View File

@@ -94,7 +94,7 @@ macro_rules! impl_try_from_object_int {
vm.new_overflow_error(concat!(
"Int value cannot fit into Rust ",
stringify!($t)
).to_string())
).to_owned())
),
}
}
@@ -144,7 +144,7 @@ fn inner_pow(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
fn inner_mod(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
if int2.is_zero() {
Err(vm.new_zero_division_error("integer modulo by zero".to_string()))
Err(vm.new_zero_division_error("integer modulo by zero".to_owned()))
} else {
Ok(vm.ctx.new_int(int1.mod_floor(int2)))
}
@@ -152,7 +152,7 @@ fn inner_mod(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
fn inner_floordiv(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
if int2.is_zero() {
Err(vm.new_zero_division_error("integer division by zero".to_string()))
Err(vm.new_zero_division_error("integer division by zero".to_owned()))
} else {
Ok(vm.ctx.new_int(int1.div_floor(&int2)))
}
@@ -160,7 +160,7 @@ fn inner_floordiv(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult
fn inner_divmod(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
if int2.is_zero() {
Err(vm.new_zero_division_error("integer division or modulo by zero".to_string()))
Err(vm.new_zero_division_error("integer division or modulo by zero".to_owned()))
} else {
let (div, modulo) = int1.div_mod_floor(int2);
Ok(vm
@@ -182,7 +182,7 @@ fn inner_rshift(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
#[inline]
fn inner_truediv(i1: &BigInt, i2: &BigInt, vm: &VirtualMachine) -> PyResult {
if i2.is_zero() {
return Err(vm.new_zero_division_error("integer division by zero".to_string()));
return Err(vm.new_zero_division_error("integer division by zero".to_owned()));
}
if let (Some(f1), Some(f2)) = (i1.to_f64(), i2.to_f64()) {
@@ -206,7 +206,7 @@ fn inner_truediv(i1: &BigInt, i2: &BigInt, vm: &VirtualMachine) -> PyResult {
Ok(vm.ctx.new_float(quotient + rem_part))
} else {
Err(vm.new_overflow_error("int too large to convert to float".to_string()))
Err(vm.new_overflow_error("int too large to convert to float".to_owned()))
}
}
}
@@ -413,17 +413,17 @@ impl PyInt {
}
#[pymethod(name = "__neg__")]
fn neg(&self, _vm: &VirtualMachine) -> BigInt {
fn neg(&self) -> BigInt {
-(&self.value)
}
#[pymethod(name = "__hash__")]
pub fn hash(&self, _vm: &VirtualMachine) -> pyhash::PyHash {
pub fn hash(&self) -> pyhash::PyHash {
pyhash::hash_bigint(&self.value)
}
#[pymethod(name = "__abs__")]
fn abs(&self, _vm: &VirtualMachine) -> BigInt {
fn abs(&self) -> BigInt {
self.value.abs()
}
@@ -457,12 +457,12 @@ impl PyInt {
}
#[pymethod(name = "__int__")]
fn int(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyIntRef {
fn int(zelf: PyRef<Self>) -> PyIntRef {
zelf
}
#[pymethod(name = "__pos__")]
fn pos(&self, _vm: &VirtualMachine) -> BigInt {
fn pos(&self) -> BigInt {
self.value.clone()
}
@@ -472,32 +472,32 @@ impl PyInt {
}
#[pymethod(name = "__trunc__")]
fn trunc(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyIntRef {
fn trunc(zelf: PyRef<Self>) -> PyIntRef {
zelf
}
#[pymethod(name = "__floor__")]
fn floor(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyIntRef {
fn floor(zelf: PyRef<Self>) -> PyIntRef {
zelf
}
#[pymethod(name = "__ceil__")]
fn ceil(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyIntRef {
fn ceil(zelf: PyRef<Self>) -> PyIntRef {
zelf
}
#[pymethod(name = "__index__")]
fn index(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyIntRef {
fn index(zelf: PyRef<Self>) -> PyIntRef {
zelf
}
#[pymethod(name = "__invert__")]
fn invert(&self, _vm: &VirtualMachine) -> BigInt {
fn invert(&self) -> BigInt {
!(&self.value)
}
#[pymethod(name = "__repr__")]
fn repr(&self, _vm: &VirtualMachine) -> String {
fn repr(&self) -> String {
self.value.to_string()
}
@@ -512,22 +512,22 @@ impl PyInt {
}
#[pymethod(name = "__bool__")]
fn bool(&self, _vm: &VirtualMachine) -> bool {
fn bool(&self) -> bool {
!self.value.is_zero()
}
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
fn sizeof(&self) -> usize {
size_of::<Self>() + ((self.value.bits() + 7) & !7) / 8
}
#[pymethod]
fn bit_length(&self, _vm: &VirtualMachine) -> usize {
fn bit_length(&self) -> usize {
self.value.bits()
}
#[pymethod]
fn conjugate(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyIntRef {
fn conjugate(zelf: PyRef<Self>) -> PyIntRef {
zelf
}
@@ -555,7 +555,7 @@ impl PyInt {
},
_ => {
return Err(
vm.new_value_error("byteorder must be either 'little' or 'big'".to_string())
vm.new_value_error("byteorder must be either 'little' or 'big'".to_owned())
)
}
};
@@ -573,14 +573,14 @@ impl PyInt {
let value = self.as_bigint();
if value.sign() == Sign::Minus && !signed {
return Err(vm.new_overflow_error("can't convert negative int to unsigned".to_string()));
return Err(vm.new_overflow_error("can't convert negative int to unsigned".to_owned()));
}
let byte_len = if let Some(byte_len) = args.length.as_bigint().to_usize() {
byte_len
} else {
return Err(
vm.new_overflow_error("Python int too large to convert to C ssize_t".to_string())
vm.new_overflow_error("Python int too large to convert to C ssize_t".to_owned())
);
};
@@ -595,14 +595,14 @@ impl PyInt {
},
_ => {
return Err(
vm.new_value_error("byteorder must be either 'little' or 'big'".to_string())
vm.new_value_error("byteorder must be either 'little' or 'big'".to_owned())
);
}
};
let origin_len = origin_bytes.len();
if origin_len > byte_len {
return Err(vm.new_overflow_error("int too big to convert".to_string()));
return Err(vm.new_overflow_error("int too big to convert".to_owned()));
}
let mut append_bytes = match value.sign() {
@@ -626,21 +626,22 @@ impl PyInt {
}
#[pyproperty]
fn real(&self, vm: &VirtualMachine) -> PyObjectRef {
// subclasses must return int here
vm.ctx.new_bigint(&self.value)
}
#[pyproperty]
fn imag(&self, _vm: &VirtualMachine) -> usize {
fn imag(&self) -> usize {
0
}
#[pyproperty]
fn numerator(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyIntRef {
fn numerator(zelf: PyRef<Self>) -> PyIntRef {
zelf
}
#[pyproperty]
fn denominator(&self, _vm: &VirtualMachine) -> usize {
fn denominator(&self) -> usize {
1
}
}
@@ -661,7 +662,7 @@ impl IntOptions {
|| objtype::isinstance(&val, &vm.ctx.bytes_type()))
{
return Err(vm.new_type_error(
"int() can't convert non-string with explicit base".to_string(),
"int() can't convert non-string with explicit base".to_owned(),
));
}
base
@@ -670,7 +671,7 @@ impl IntOptions {
};
to_int(vm, &val, base.as_bigint())
} else if let OptionalArg::Present(_) = self.base {
Err(vm.new_type_error("int() missing string argument".to_string()))
Err(vm.new_type_error("int() missing string argument".to_owned()))
} else {
Ok(Zero::zero())
}
@@ -702,11 +703,11 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: &BigInt) -> PyResult
let base_u32 = match base.to_u32() {
Some(base_u32) => base_u32,
None => {
return Err(vm.new_value_error("int() base must be >= 2 and <= 36, or 0".to_string()))
return Err(vm.new_value_error("int() base must be >= 2 and <= 36, or 0".to_owned()))
}
};
if base_u32 != 0 && (base_u32 < 2 || base_u32 > 36) {
return Err(vm.new_value_error("int() base must be >= 2 and <= 36, or 0".to_string()));
return Err(vm.new_value_error("int() base must be >= 2 and <= 36, or 0".to_owned()));
}
match_class!(match obj.clone() {
@@ -834,7 +835,7 @@ pub fn get_value(obj: &PyObjectRef) -> &BigInt {
pub fn try_float(int: &BigInt, vm: &VirtualMachine) -> PyResult<f64> {
int.to_f64()
.ok_or_else(|| vm.new_overflow_error("int too large to convert to float".to_string()))
.ok_or_else(|| vm.new_overflow_error("int too large to convert to float".to_owned()))
}
fn get_shift_amount(amount: &BigInt, vm: &VirtualMachine) -> PyResult<usize> {
@@ -842,9 +843,9 @@ fn get_shift_amount(amount: &BigInt, vm: &VirtualMachine) -> PyResult<usize> {
Ok(n_bits)
} else {
match amount {
v if *v < BigInt::zero() => Err(vm.new_value_error("negative shift count".to_string())),
v if *v < BigInt::zero() => Err(vm.new_value_error("negative shift count".to_owned())),
v if *v > BigInt::from(usize::max_value()) => {
Err(vm.new_overflow_error("the number is too large to convert to int".to_string()))
Err(vm.new_overflow_error("the number is too large to convert to int".to_owned()))
}
_ => panic!("Failed converting {} to rust usize", amount),
}

View File

@@ -128,10 +128,10 @@ pub fn length_hint(vm: &VirtualMachine, iter: PyObjectRef) -> PyResult<Option<us
})?
.as_bigint();
if result.is_negative() {
return Err(vm.new_value_error("__length_hint__() should return >= 0".to_string()));
return Err(vm.new_value_error("__length_hint__() should return >= 0".to_owned()));
}
let hint = result.to_usize().ok_or_else(|| {
vm.new_value_error("Python int too large to convert to Rust usize".to_string())
vm.new_value_error("Python int too large to convert to Rust usize".to_owned())
})?;
Ok(Some(hint))
}
@@ -174,7 +174,7 @@ impl PySequenceIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
@@ -185,7 +185,7 @@ impl PySequenceIterator {
pos + 1
} else {
let len = objsequence::opt_len(&self.obj, vm).unwrap_or_else(|| {
Err(vm.new_type_error("sequence has no __len__ method".to_string()))
Err(vm.new_type_error("sequence has no __len__ method".to_owned()))
})?;
len as isize - pos
};
@@ -193,7 +193,7 @@ impl PySequenceIterator {
}
}
pub fn seq_iter_method(obj: PyObjectRef, _vm: &VirtualMachine) -> PySequenceIterator {
pub fn seq_iter_method(obj: PyObjectRef) -> PySequenceIterator {
PySequenceIterator {
position: Cell::new(0),
obj,

View File

@@ -119,9 +119,7 @@ impl PyList {
Ok(result) => match result.as_bigint().to_u8() {
Some(result) => elements.push(result),
None => {
return Err(
vm.new_value_error("bytes must be in range (0, 256)".to_string())
)
return Err(vm.new_value_error("bytes must be in range (0, 256)".to_owned()))
}
},
_ => {
@@ -149,7 +147,7 @@ pub type PyListRef = PyRef<PyList>;
#[pyimpl(flags(BASETYPE))]
impl PyList {
#[pymethod]
pub(crate) fn append(&self, x: PyObjectRef, _vm: &VirtualMachine) {
pub(crate) fn append(&self, x: PyObjectRef) {
self.elements.borrow_mut().push(x);
}
@@ -161,7 +159,7 @@ impl PyList {
}
#[pymethod]
fn insert(&self, position: isize, element: PyObjectRef, _vm: &VirtualMachine) {
fn insert(&self, position: isize, element: PyObjectRef) {
let mut vec = self.elements.borrow_mut();
let vec_len = vec.len().to_isize().unwrap();
// This unbounded position can be < 0 or > vec.len()
@@ -203,12 +201,12 @@ impl PyList {
}
#[pymethod(name = "__bool__")]
fn bool(&self, _vm: &VirtualMachine) -> bool {
fn bool(&self) -> bool {
!self.elements.borrow().is_empty()
}
#[pymethod]
fn clear(&self, _vm: &VirtualMachine) {
fn clear(&self) {
self.elements.borrow_mut().clear();
}
@@ -218,22 +216,22 @@ impl PyList {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.elements.borrow().len()
}
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
fn sizeof(&self) -> usize {
size_of::<Self>() + self.elements.borrow().capacity() * size_of::<PyObjectRef>()
}
#[pymethod]
fn reverse(&self, _vm: &VirtualMachine) {
fn reverse(&self) {
self.elements.borrow_mut().reverse();
}
#[pymethod(name = "__reversed__")]
fn reversed(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyListReverseIterator {
fn reversed(zelf: PyRef<Self>) -> PyListReverseIterator {
let final_position = zelf.elements.borrow().len();
PyListReverseIterator {
position: Cell::new(final_position),
@@ -252,7 +250,7 @@ impl PyList {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyListIterator {
fn iter(zelf: PyRef<Self>) -> PyListIterator {
PyListIterator {
position: Cell::new(0),
list: zelf,
@@ -272,7 +270,7 @@ impl PyList {
if let Ok(sec) = PyIterable::try_from_object(vm, value) {
return self.setslice(slice, sec, vm);
}
Err(vm.new_type_error("can only assign an iterable to a slice".to_string()))
Err(vm.new_type_error("can only assign an iterable to a slice".to_owned()))
}
}
}
@@ -282,7 +280,7 @@ impl PyList {
self.elements.borrow_mut()[pos_index] = value;
Ok(vm.get_none())
} else {
Err(vm.new_index_error("list assignment index out of range".to_string()))
Err(vm.new_index_error("list assignment index out of range".to_owned()))
}
}
@@ -290,7 +288,7 @@ impl PyList {
let step = slice.step_index(vm)?.unwrap_or_else(BigInt::one);
if step.is_zero() {
Err(vm.new_value_error("slice step cannot be zero".to_string()))
Err(vm.new_value_error("slice step cannot be zero".to_owned()))
} else if step.is_positive() {
let range = self.get_slice_range(&slice.start_index(vm)?, &slice.stop_index(vm)?);
if range.start < range.end {
@@ -455,18 +453,18 @@ impl PyList {
let mut str_parts = Vec::with_capacity(zelf.elements.borrow().len());
for elem in zelf.elements.borrow().iter() {
let s = vm.to_repr(elem)?;
str_parts.push(s.as_str().to_string());
str_parts.push(s.as_str().to_owned());
}
format!("[{}]", str_parts.join(", "))
} else {
"[...]".to_string()
"[...]".to_owned()
};
Ok(s)
}
#[pymethod(name = "__hash__")]
fn hash(&self, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_type_error("unhashable type".to_string()))
Err(vm.new_type_error("unhashable type".to_owned()))
}
#[pymethod(name = "__mul__")]
@@ -483,7 +481,7 @@ impl PyList {
}
#[pymethod(name = "__imul__")]
fn imul(zelf: PyRef<Self>, counter: isize, _vm: &VirtualMachine) -> PyRef<Self> {
fn imul(zelf: PyRef<Self>, counter: isize) -> PyRef<Self> {
let new_elements = sequence::seq_mul(&zelf.borrow_sequence(), counter)
.cloned()
.collect();
@@ -532,9 +530,9 @@ impl PyList {
i += elements.len() as isize;
}
if elements.is_empty() {
Err(vm.new_index_error("pop from empty list".to_string()))
Err(vm.new_index_error("pop from empty list".to_owned()))
} else if i < 0 || i as usize >= elements.len() {
Err(vm.new_index_error("pop index out of range".to_string()))
Err(vm.new_index_error("pop index out of range".to_owned()))
} else {
Ok(elements.remove(i as usize))
}
@@ -627,7 +625,7 @@ impl PyList {
self.elements.borrow_mut().remove(pos_index);
Ok(())
} else {
Err(vm.new_index_error("Index out of bounds!".to_string()))
Err(vm.new_index_error("Index out of bounds!".to_owned()))
}
}
@@ -637,7 +635,7 @@ impl PyList {
let step = slice.step_index(vm)?.unwrap_or_else(BigInt::one);
if step.is_zero() {
Err(vm.new_value_error("slice step cannot be zero".to_string()))
Err(vm.new_value_error("slice step cannot be zero".to_owned()))
} else if step.is_positive() {
let range = self.get_slice_range(&start, &stop);
if range.start < range.end {
@@ -756,7 +754,7 @@ impl PyList {
let temp_elements = self.elements.replace(elements);
if !temp_elements.is_empty() {
return Err(vm.new_value_error("list modified during sort".to_string()));
return Err(vm.new_value_error("list modified during sort".to_owned()));
}
Ok(())
@@ -870,12 +868,12 @@ impl PyListIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
#[pymethod(name = "__length_hint__")]
fn length_hint(&self, _vm: &VirtualMachine) -> usize {
fn length_hint(&self) -> usize {
self.list.elements.borrow().len() - self.position.get()
}
}
@@ -908,12 +906,12 @@ impl PyListReverseIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
#[pymethod(name = "__length_hint__")]
fn length_hint(&self, _vm: &VirtualMachine) -> usize {
fn length_hint(&self) -> usize {
self.position.get()
}
}

View File

@@ -55,7 +55,7 @@ impl PyMap {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}

View File

@@ -1,9 +1,6 @@
use super::objproperty::PyPropertyRef;
use super::objstr::PyStringRef;
use super::objtype::PyClassRef;
use crate::pyobject::{
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -43,75 +40,15 @@ impl PyNone {
}
#[pymethod(name = "__repr__")]
fn repr(&self, _vm: &VirtualMachine) -> PyResult<String> {
Ok("None".to_string())
fn repr(&self) -> PyResult<String> {
Ok("None".to_owned())
}
#[pymethod(name = "__bool__")]
fn bool(&self, _vm: &VirtualMachine) -> PyResult<bool> {
fn bool(&self) -> PyResult<bool> {
Ok(false)
}
#[pymethod(name = "__getattribute__")]
fn get_attribute(zelf: PyRef<Self>, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
vm_trace!("None.__getattribute__({:?}, {:?})", self, name);
let cls = zelf.class();
// Properties use a comparision with None to determine if they are either invoked by am
// instance binding or a class binding. But if the object itself is None then this detection
// won't work. Instead we call a special function on property that bypasses this check, as
// we are invoking it as a instance binding.
//
// In CPython they instead call the slot tp_descr_get with NULL to indicates it's an
// instance binding.
// https://github.com/python/cpython/blob/master/Objects/typeobject.c#L3281
fn call_descriptor(
descriptor: PyObjectRef,
get_func: PyObjectRef,
obj: PyObjectRef,
cls: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
if let Ok(property) = PyPropertyRef::try_from_object(vm, descriptor.clone()) {
property.instance_binding_get(obj, vm)
} else {
vm.invoke(&get_func, vec![descriptor, obj, cls])
}
}
if let Some(attr) = cls.get_attr(name.as_str()) {
let attr_class = attr.class();
if attr_class.has_attr("__set__") {
if let Some(get_func) = attr_class.get_attr("__get__") {
return call_descriptor(
attr,
get_func,
zelf.into_object(),
cls.into_object(),
vm,
);
}
}
}
// None has no attributes and cannot have attributes set on it.
// if let Some(obj_attr) = zelf.as_object().get_attr(name.as_str()) {
// Ok(obj_attr)
// } else
if let Some(attr) = cls.get_attr(name.as_str()) {
let attr_class = attr.class();
if let Some(get_func) = attr_class.get_attr("__get__") {
call_descriptor(attr, get_func, zelf.into_object(), cls.into_object(), vm)
} else {
Ok(attr)
}
} else if let Some(getter) = cls.get_attr("__getattr__") {
vm.invoke(&getter, vec![zelf.into_object(), name.into_object()])
} else {
Err(vm.new_attribute_error(format!("{} has no attribute '{}'", zelf.as_object(), name)))
}
}
#[pymethod(name = "__eq__")]
fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
if vm.is_none(&rhs) {

View File

@@ -37,7 +37,7 @@ impl PyBaseObject {
}
#[pymethod(magic)]
fn eq(zelf: PyObjectRef, other: PyObjectRef, _vm: &VirtualMachine) -> PyComparisonValue {
fn eq(zelf: PyObjectRef, other: PyObjectRef) -> PyComparisonValue {
if zelf.is(&other) {
Implemented(true)
} else {
@@ -64,27 +64,27 @@ impl PyBaseObject {
}
#[pymethod(magic)]
fn lt(_zelf: PyObjectRef, _other: PyObjectRef, _vm: &VirtualMachine) -> PyComparisonValue {
fn lt(_zelf: PyObjectRef, _other: PyObjectRef) -> PyComparisonValue {
NotImplemented
}
#[pymethod(magic)]
fn le(_zelf: PyObjectRef, _other: PyObjectRef, _vm: &VirtualMachine) -> PyComparisonValue {
fn le(_zelf: PyObjectRef, _other: PyObjectRef) -> PyComparisonValue {
NotImplemented
}
#[pymethod(magic)]
fn gt(_zelf: PyObjectRef, _other: PyObjectRef, _vm: &VirtualMachine) -> PyComparisonValue {
fn gt(_zelf: PyObjectRef, _other: PyObjectRef) -> PyComparisonValue {
NotImplemented
}
#[pymethod(magic)]
fn ge(_zelf: PyObjectRef, _other: PyObjectRef, _vm: &VirtualMachine) -> PyComparisonValue {
fn ge(_zelf: PyObjectRef, _other: PyObjectRef) -> PyComparisonValue {
NotImplemented
}
#[pymethod(magic)]
fn hash(zelf: PyObjectRef, _vm: &VirtualMachine) -> pyhash::PyHash {
fn hash(zelf: PyObjectRef) -> pyhash::PyHash {
zelf.get_id() as pyhash::PyHash
}
@@ -126,7 +126,7 @@ impl PyBaseObject {
}
#[pymethod(magic)]
fn repr(zelf: PyObjectRef, _vm: &VirtualMachine) -> String {
fn repr(zelf: PyObjectRef) -> String {
format!("<{} object at 0x{:x}>", zelf.class().name, zelf.get_id())
}
@@ -175,12 +175,12 @@ impl PyBaseObject {
}
#[pyproperty(name = "__class__")]
fn _class(obj: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef {
fn get_class(obj: PyObjectRef) -> PyObjectRef {
obj.class().into_object()
}
#[pyproperty(name = "__class__", setter)]
fn _set_class(instance: PyObjectRef, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn set_class(instance: PyObjectRef, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let type_repr = vm.to_pystr(&instance.class())?;
Err(vm.new_type_error(format!("can't change class of type '{}'", type_repr)))
}

View File

@@ -4,51 +4,13 @@
use std::cell::RefCell;
use super::objtype::PyClassRef;
use crate::function::{IntoPyNativeFunc, OptionalArg};
use crate::function::OptionalArg;
use crate::pyobject::{
IdProtocol, PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
TypeProtocol,
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::slots::PyBuiltinDescriptor;
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;
// Read-only property, doesn't have __set__ or __delete__
#[pyclass]
#[derive(Debug)]
pub struct PyReadOnlyProperty {
getter: PyObjectRef,
}
impl PyValue for PyReadOnlyProperty {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.ctx.readonly_property_type()
}
}
pub type PyReadOnlyPropertyRef = PyRef<PyReadOnlyProperty>;
impl PyBuiltinDescriptor for PyReadOnlyProperty {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
if vm.is_none(&obj) {
if Self::_cls_is(&cls, &vm.ctx.types.type_type) {
vm.invoke(&zelf.getter, cls.unwrap())
} else {
Ok(zelf.into_object())
}
} else {
vm.invoke(&zelf.getter, obj)
}
}
}
#[pyimpl(with(PyBuiltinDescriptor))]
impl PyReadOnlyProperty {}
/// Property attribute.
///
/// fget
@@ -110,26 +72,28 @@ struct PropertyArgs {
doc: Option<PyObjectRef>,
}
impl PyBuiltinDescriptor for PyProperty {
fn get(
zelf: PyRef<Self>,
obj: PyObjectRef,
_cls: OptionalArg<PyObjectRef>,
impl SlotDescriptor for PyProperty {
#[allow(clippy::collapsible_if)]
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
_cls: OptionalArg<PyObjectRef>,
) -> PyResult {
if let Some(getter) = zelf.getter.as_ref() {
if obj.is(vm.ctx.none.as_object()) {
Ok(zelf.into_object())
} else {
vm.invoke(&getter, obj)
}
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
if vm.is_none(&obj) {
Ok(zelf.into_object())
} else {
Err(vm.new_attribute_error("unreadable attribute".to_string()))
if let Some(getter) = zelf.getter.as_ref() {
vm.invoke(&getter, obj)
} else {
Err(vm.new_attribute_error("unreadable attribute".to_string()))
}
}
}
}
#[pyimpl(with(PyBuiltinDescriptor), flags(BASETYPE))]
#[pyimpl(with(SlotDescriptor), flags(BASETYPE))]
impl PyProperty {
#[pyslot]
fn tp_new(cls: PyClassRef, args: PropertyArgs, vm: &VirtualMachine) -> PyResult<PyPropertyRef> {
@@ -144,21 +108,12 @@ impl PyProperty {
// Descriptor methods
// specialised version that doesn't check for None
pub(crate) fn instance_binding_get(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(ref getter) = self.getter.as_ref() {
vm.invoke(getter, obj)
} else {
Err(vm.new_attribute_error("unreadable attribute".to_string()))
}
}
#[pymethod(name = "__set__")]
fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(ref setter) = self.setter.as_ref() {
vm.invoke(setter, vec![obj, value])
} else {
Err(vm.new_attribute_error("can't set attribute".to_string()))
Err(vm.new_attribute_error("can't set attribute".to_owned()))
}
}
@@ -167,28 +122,28 @@ impl PyProperty {
if let Some(ref deleter) = self.deleter.as_ref() {
vm.invoke(deleter, obj)
} else {
Err(vm.new_attribute_error("can't delete attribute".to_string()))
Err(vm.new_attribute_error("can't delete attribute".to_owned()))
}
}
// Access functions
#[pyproperty]
fn fget(&self, _vm: &VirtualMachine) -> Option<PyObjectRef> {
fn fget(&self) -> Option<PyObjectRef> {
self.getter.clone()
}
#[pyproperty]
fn fset(&self, _vm: &VirtualMachine) -> Option<PyObjectRef> {
fn fset(&self) -> Option<PyObjectRef> {
self.setter.clone()
}
#[pyproperty]
fn fdel(&self, _vm: &VirtualMachine) -> Option<PyObjectRef> {
fn fdel(&self) -> Option<PyObjectRef> {
self.deleter.clone()
}
fn doc_getter(&self, _vm: &VirtualMachine) -> Option<PyObjectRef> {
fn doc_getter(&self) -> Option<PyObjectRef> {
self.doc.borrow().clone()
}
@@ -253,81 +208,12 @@ fn py_none_to_option(vm: &VirtualMachine, value: &PyObjectRef) -> Option<PyObjec
}
}
pub struct PropertyBuilder<'a> {
ctx: &'a PyContext,
getter: Option<PyObjectRef>,
setter: Option<PyObjectRef>,
}
pub trait PropertySetterResult {}
impl PropertySetterResult for PyResult<()> {}
impl PropertySetterResult for () {}
impl<'a> PropertyBuilder<'a> {
pub fn new(ctx: &'a PyContext) -> Self {
Self {
ctx,
getter: None,
setter: None,
}
}
pub fn add_getter<I, V, VM, F: IntoPyNativeFunc<I, V, VM>>(self, func: F) -> Self {
let func = self.ctx.new_method(func);
Self {
ctx: self.ctx,
getter: Some(func),
setter: self.setter,
}
}
pub fn add_setter<I, V, VM, F: IntoPyNativeFunc<(I, V), impl PropertySetterResult, VM>>(
self,
func: F,
) -> Self {
let func = self.ctx.new_method(func);
Self {
ctx: self.ctx,
getter: self.getter,
setter: Some(func),
}
}
pub fn create(self) -> PyObjectRef {
if self.setter.is_some() {
let payload = PyProperty {
getter: self.getter.clone(),
setter: self.setter.clone(),
deleter: None,
doc: RefCell::new(None),
};
PyObject::new(payload, self.ctx.property_type(), None)
} else {
let payload = PyReadOnlyProperty {
getter: self.getter.expect(
"One of add_getter/add_setter must be called when constructing a property",
),
};
PyObject::new(payload, self.ctx.readonly_property_type(), None)
}
}
}
pub fn init(context: &PyContext) {
PyReadOnlyProperty::extend_class(context, &context.types.readonly_property_type);
pub(crate) fn init(context: &PyContext) {
PyProperty::extend_class(context, &context.types.property_type);
// This is a bit unfortunate, but this instance attribute overlaps with the
// class __doc__ string..
extend_class!(context, &context.types.property_type, {
"__doc__" =>
PropertyBuilder::new(context)
.add_getter(PyProperty::doc_getter)
.add_setter(PyProperty::doc_setter)
.create(),
"__doc__" => context.new_getset("__doc__", PyProperty::doc_getter, PyProperty::doc_setter),
});
}

View File

@@ -148,28 +148,28 @@ impl PyRange {
) -> PyResult<PyRangeRef> {
let step = step.unwrap_or_else(|| PyInt::new(BigInt::one()).into_ref(vm));
if step.as_bigint().is_zero() {
return Err(vm.new_value_error("range() arg 3 must not be zero".to_string()));
return Err(vm.new_value_error("range() arg 3 must not be zero".to_owned()));
}
PyRange { start, stop, step }.into_ref_with_type(vm, cls)
}
#[pyproperty(name = "start")]
fn start(&self, _vm: &VirtualMachine) -> PyIntRef {
fn start(&self) -> PyIntRef {
self.start.clone()
}
#[pyproperty(name = "stop")]
fn stop(&self, _vm: &VirtualMachine) -> PyIntRef {
fn stop(&self) -> PyIntRef {
self.stop.clone()
}
#[pyproperty(name = "step")]
fn step(&self, _vm: &VirtualMachine) -> PyIntRef {
fn step(&self) -> PyIntRef {
self.step.clone()
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRangeIterator {
fn iter(zelf: PyRef<Self>) -> PyRangeIterator {
PyRangeIterator {
position: Cell::new(0),
range: zelf,
@@ -210,12 +210,12 @@ impl PyRange {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> BigInt {
fn len(&self) -> BigInt {
self.length()
}
#[pymethod(name = "__repr__")]
fn repr(&self, _vm: &VirtualMachine) -> String {
fn repr(&self) -> String {
if self.step.as_bigint().is_one() {
format!("range({}, {})", self.start, self.stop)
} else {
@@ -224,12 +224,12 @@ impl PyRange {
}
#[pymethod(name = "__bool__")]
fn bool(&self, _vm: &VirtualMachine) -> bool {
fn bool(&self) -> bool {
!self.is_empty()
}
#[pymethod(name = "__contains__")]
fn contains(&self, needle: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn contains(&self, needle: PyObjectRef) -> bool {
if let Ok(int) = needle.downcast::<PyInt>() {
match self.offset(int.as_bigint()) {
Some(ref offset) => offset.is_multiple_of(self.step.as_bigint()),
@@ -318,12 +318,12 @@ impl PyRange {
None => Err(vm.new_value_error(format!("{} is not in range", int))),
}
} else {
Err(vm.new_value_error("sequence.index(x): x not in sequence".to_string()))
Err(vm.new_value_error("sequence.index(x): x not in sequence".to_owned()))
}
}
#[pymethod(name = "count")]
fn count(&self, item: PyObjectRef, _vm: &VirtualMachine) -> usize {
fn count(&self, item: PyObjectRef) -> usize {
if let Ok(int) = item.downcast::<PyInt>() {
if self.index_of(int.as_bigint()).is_some() {
1
@@ -341,8 +341,8 @@ impl PyRange {
RangeIndex::Slice(slice) => {
let (mut substart, mut substop, mut substep) =
slice.inner_indices(&self.length(), vm)?;
let range_step = self.step(vm);
let range_start = self.start(vm);
let range_step = &self.step;
let range_start = &self.start;
substep *= range_step.as_bigint();
substart = (substart * range_step.as_bigint()) + range_start.as_bigint();
@@ -358,7 +358,7 @@ impl PyRange {
}
RangeIndex::Int(index) => match self.get(index.as_bigint()) {
Some(value) => Ok(PyInt::new(value).into_ref(vm).into_object()),
None => Err(vm.new_index_error("range object index out of range".to_string())),
None => Err(vm.new_index_error("range object index out of range".to_owned())),
},
}
}
@@ -371,14 +371,14 @@ impl PyRange {
} else if length.is_one() {
vec![
vm.ctx.new_int(length),
zelf.start(vm).into_object(),
zelf.start().into_object(),
vm.get_none(),
]
} else {
vec![
vm.ctx.new_int(length),
zelf.start(vm).into_object(),
zelf.step(vm).into_object(),
zelf.start().into_object(),
zelf.step().into_object(),
]
};
pyhash::hash_iter(elements.iter(), vm)
@@ -427,7 +427,7 @@ impl PyRangeIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRangeIteratorRef {
fn iter(zelf: PyRef<Self>) -> PyRangeIteratorRef {
zelf
}
}

View File

@@ -73,7 +73,7 @@ pub trait PySliceableSequence {
let stop = slice.stop_index(vm)?;
let step = slice.step_index(vm)?.unwrap_or_else(BigInt::one);
if step.is_zero() {
Err(vm.new_value_error("slice step cannot be zero".to_string()))
Err(vm.new_value_error("slice step cannot be zero".to_owned()))
} else if step.is_positive() {
let range = self.get_slice_range(&start, &stop);
if range.start < range.end {
@@ -182,7 +182,7 @@ pub fn get_sequence_index(vm: &VirtualMachine, index: &PyIntRef, length: usize)
if value < 0 {
let from_end: usize = -value as usize;
if from_end > length {
Err(vm.new_index_error("Index out of bounds!".to_string()))
Err(vm.new_index_error("Index out of bounds!".to_owned()))
} else {
let index = length - from_end;
Ok(index)
@@ -190,13 +190,13 @@ pub fn get_sequence_index(vm: &VirtualMachine, index: &PyIntRef, length: usize)
} else {
let index = value as usize;
if index >= length {
Err(vm.new_index_error("Index out of bounds!".to_string()))
Err(vm.new_index_error("Index out of bounds!".to_owned()))
} else {
Ok(index)
}
}
} else {
Err(vm.new_index_error("cannot fit 'int' into an index-sized integer".to_string()))
Err(vm.new_index_error("cannot fit 'int' into an index-sized integer".to_owned()))
}
}
@@ -213,11 +213,11 @@ pub fn get_item(
let obj = elements[pos_index].clone();
Ok(obj)
} else {
Err(vm.new_index_error("Index out of bounds!".to_string()))
Err(vm.new_index_error("Index out of bounds!".to_owned()))
}
}
None => {
Err(vm.new_index_error("cannot fit 'int' into an index-sized integer".to_string()))
Err(vm.new_index_error("cannot fit 'int' into an index-sized integer".to_owned()))
}
};
}
@@ -256,7 +256,7 @@ pub fn is_valid_slice_arg(
i @ PyInt => Ok(Some(i.as_bigint().clone())),
_obj @ PyNone => Ok(None),
_ => Err(vm.new_type_error(
"slice indices must be integers or None or have an __index__ method".to_string()
"slice indices must be integers or None or have an __index__ method".to_owned()
)), // TODO: check for an __index__ method
})
} else {
@@ -277,10 +277,10 @@ pub fn opt_len(obj: &PyObjectRef, vm: &VirtualMachine) -> Option<PyResult<usize>
})?
.as_bigint();
if len.is_negative() {
return Err(vm.new_value_error("__len__() should return >= 0".to_string()));
return Err(vm.new_value_error("__len__() should return >= 0".to_owned()));
}
len.to_usize().ok_or_else(|| {
vm.new_overflow_error("cannot fit __len__() result into usize".to_string())
vm.new_overflow_error("cannot fit __len__() result into usize".to_owned())
})
})
}

View File

@@ -275,7 +275,7 @@ impl PySetInner {
if let Some((key, _)) = self.content.pop_front() {
Ok(key)
} else {
let err_msg = vm.new_str("pop from an empty set".to_string());
let err_msg = vm.new_str("pop from an empty set".to_owned());
Err(vm.new_key_error(err_msg))
}
}
@@ -343,17 +343,17 @@ impl PySet {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.inner.borrow().len()
}
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
fn sizeof(&self) -> usize {
std::mem::size_of::<Self>() + self.inner.borrow().sizeof()
}
#[pymethod]
fn copy(&self, _vm: &VirtualMachine) -> Self {
fn copy(&self) -> Self {
Self {
inner: RefCell::new(self.inner.borrow().copy()),
}
@@ -486,11 +486,11 @@ impl PySet {
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
let inner = zelf.inner.borrow();
let s = if inner.len() == 0 {
"set()".to_string()
"set()".to_owned()
} else if let Some(_guard) = ReprGuard::enter(zelf.as_object()) {
inner.repr(vm)?
} else {
"set(...)".to_string()
"set(...)".to_owned()
};
Ok(vm.new_str(s))
}
@@ -513,7 +513,7 @@ impl PySet {
}
#[pymethod]
fn clear(&self, _vm: &VirtualMachine) {
fn clear(&self) {
self.inner.borrow_mut().clear()
}
@@ -580,7 +580,7 @@ impl PySet {
#[pymethod(name = "__hash__")]
fn hash(&self, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_type_error("unhashable type".to_string()))
Err(vm.new_type_error("unhashable type".to_owned()))
}
}
@@ -599,17 +599,17 @@ impl PyFrozenSet {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.inner.len()
}
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
fn sizeof(&self) -> usize {
std::mem::size_of::<Self>() + self.inner.sizeof()
}
#[pymethod]
fn copy(&self, _vm: &VirtualMachine) -> Self {
fn copy(&self) -> Self {
Self {
inner: self.inner.copy(),
}
@@ -742,11 +742,11 @@ impl PyFrozenSet {
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
let inner = &zelf.inner;
let s = if inner.len() == 0 {
"frozenset()".to_string()
"frozenset()".to_owned()
} else if let Some(_guard) = ReprGuard::enter(zelf.as_object()) {
format!("frozenset({})", inner.repr(vm)?)
} else {
"frozenset(...)".to_string()
"frozenset(...)".to_owned()
};
Ok(vm.new_str(s))
}

View File

@@ -51,14 +51,14 @@ impl PySlice {
}
#[pymethod(name = "__repr__")]
fn repr(&self, _vm: &VirtualMachine) -> PyResult<String> {
let start = self.start(_vm);
let stop = self.stop(_vm);
let step = self.step(_vm);
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
let start = self.start(vm);
let stop = self.stop(vm);
let step = self.step(vm);
let start_repr = _vm.to_repr(&start)?;
let stop_repr = _vm.to_repr(&stop)?;
let step_repr = _vm.to_repr(&step)?;
let start_repr = vm.to_repr(&start)?;
let stop_repr = vm.to_repr(&stop)?;
let step_repr = vm.to_repr(&step)?;
Ok(format!(
"slice({}, {}, {})",
@@ -302,7 +302,7 @@ impl PySlice {
#[pymethod(name = "__hash__")]
fn hash(&self, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_type_error("unhashable type".to_string()))
Err(vm.new_type_error("unhashable type".to_owned()))
}
#[pymethod(name = "indices")]
@@ -332,11 +332,11 @@ fn to_index_value(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Option<Big
if let Some(val) = index_result.payload::<PyInt>() {
Ok(Some(val.as_bigint().clone()))
} else {
Err(vm.new_type_error("__index__ method returned non integer".to_string()))
Err(vm.new_type_error("__index__ method returned non integer".to_owned()))
}
} else {
Err(vm.new_type_error(
"slice indices must be integers or None or have an __index__ method".to_string(),
"slice indices must be integers or None or have an __index__ method".to_owned(),
))
}
}

View File

@@ -1,7 +1,7 @@
use super::objtype::PyClassRef;
use crate::function::OptionalArg;
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
use crate::slots::PyBuiltinDescriptor;
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;
#[pyclass(name = "staticmethod")]
@@ -17,18 +17,19 @@ impl PyValue for PyStaticMethod {
}
}
impl PyBuiltinDescriptor for PyStaticMethod {
fn get(
zelf: PyRef<Self>,
_obj: PyObjectRef,
impl SlotDescriptor for PyStaticMethod {
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
_obj: Option<PyObjectRef>,
_cls: OptionalArg<PyObjectRef>,
_vm: &VirtualMachine,
) -> PyResult {
let zelf = Self::_zelf(zelf, vm)?;
Ok(zelf.callable.clone())
}
}
#[pyimpl(with(PyBuiltinDescriptor), flags(BASETYPE))]
#[pyimpl(with(SlotDescriptor), flags(BASETYPE))]
impl PyStaticMethod {
#[pyslot]
fn tp_new(

View File

@@ -61,7 +61,7 @@ impl PyString {
impl From<&str> for PyString {
fn from(s: &str) -> PyString {
s.to_string().into()
s.to_owned().into()
}
}
@@ -127,7 +127,7 @@ impl PyStringIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -163,7 +163,7 @@ impl PyStringReverseIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -225,7 +225,7 @@ impl PyString {
}
#[pymethod(name = "__bool__")]
fn bool(&self, _vm: &VirtualMachine) -> bool {
fn bool(&self) -> bool {
!self.value.is_empty()
}
@@ -248,7 +248,7 @@ impl PyString {
}
#[pymethod(name = "__contains__")]
fn contains(&self, needle: PyStringRef, _vm: &VirtualMachine) -> bool {
fn contains(&self, needle: PyStringRef) -> bool {
self.value.contains(&needle.value)
}
@@ -266,17 +266,18 @@ impl PyString {
if let Some(character) = self.value.chars().nth(index) {
Ok(vm.new_str(character.to_string()))
} else {
Err(vm.new_index_error("string index out of range".to_string()))
Err(vm.new_index_error("string index out of range".to_owned()))
}
}
None => Err(
vm.new_index_error("cannot fit 'int' into an index-sized integer".to_string())
),
None => {
Err(vm
.new_index_error("cannot fit 'int' into an index-sized integer".to_owned()))
}
},
Either::B(slice) => {
let string = self
.value
.to_string()
.to_owned()
.get_slice_items(vm, slice.as_object())?;
Ok(vm.new_str(string))
}
@@ -284,27 +285,27 @@ impl PyString {
}
#[pymethod(name = "__gt__")]
fn gt(&self, other: PyStringRef, _vm: &VirtualMachine) -> bool {
fn gt(&self, other: PyStringRef) -> bool {
self.value > other.value
}
#[pymethod(name = "__ge__")]
fn ge(&self, other: PyStringRef, _vm: &VirtualMachine) -> bool {
fn ge(&self, other: PyStringRef) -> bool {
self.value >= other.value
}
#[pymethod(name = "__lt__")]
fn lt(&self, other: PyStringRef, _vm: &VirtualMachine) -> bool {
fn lt(&self, other: PyStringRef) -> bool {
self.value < other.value
}
#[pymethod(name = "__le__")]
fn le(&self, other: PyStringRef, _vm: &VirtualMachine) -> bool {
fn le(&self, other: PyStringRef) -> bool {
self.value <= other.value
}
#[pymethod(name = "__hash__")]
fn hash(&self, _vm: &VirtualMachine) -> pyhash::PyHash {
fn hash(&self) -> pyhash::PyHash {
match self.hash.get() {
Some(hash) => hash,
None => {
@@ -316,12 +317,12 @@ impl PyString {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.value.chars().count()
}
#[pymethod(name = "__sizeof__")]
fn sizeof(&self, _vm: &VirtualMachine) -> usize {
fn sizeof(&self) -> usize {
size_of::<Self>() + self.value.capacity() * size_of::<u8>()
}
@@ -332,7 +333,7 @@ impl PyString {
.to_usize()
.map(|multiplier| self.value.repeat(multiplier))
.ok_or_else(|| {
vm.new_overflow_error("cannot fit 'int' into an index-sized integer".to_string())
vm.new_overflow_error("cannot fit 'int' into an index-sized integer".to_owned())
})
}
@@ -342,12 +343,12 @@ impl PyString {
}
#[pymethod(name = "__str__")]
fn str(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyStringRef {
fn str(zelf: PyRef<Self>) -> PyStringRef {
zelf
}
#[pymethod(name = "__repr__")]
fn repr(&self, _vm: &VirtualMachine) -> String {
fn repr(&self) -> String {
let value = &self.value;
let quote_char = if count_char(value, '\'') > count_char(value, '"') {
'"'
@@ -389,23 +390,23 @@ impl PyString {
}
#[pymethod]
fn lower(&self, _vm: &VirtualMachine) -> String {
fn lower(&self) -> String {
self.value.to_lowercase()
}
// casefold is much more aggressive than lower
#[pymethod]
fn casefold(&self, _vm: &VirtualMachine) -> String {
fn casefold(&self) -> String {
caseless::default_case_fold_str(&self.value)
}
#[pymethod]
fn upper(&self, _vm: &VirtualMachine) -> String {
fn upper(&self) -> String {
self.value.to_uppercase()
}
#[pymethod]
fn capitalize(&self, _vm: &VirtualMachine) -> String {
fn capitalize(&self) -> String {
let (first_part, lower_str) = self.value.split_at(1);
format!("{}{}", first_part.to_uppercase(), lower_str)
}
@@ -418,21 +419,21 @@ impl PyString {
let elements: Vec<_> = match (pattern, num_splits.is_negative()) {
(Some(pattern), true) => value
.split(pattern)
.map(|o| vm.ctx.new_str(o.to_string()))
.map(|o| vm.ctx.new_str(o.to_owned()))
.collect(),
(Some(pattern), false) => value
.splitn(num_splits as usize + 1, pattern)
.map(|o| vm.ctx.new_str(o.to_string()))
.map(|o| vm.ctx.new_str(o.to_owned()))
.collect(),
(None, true) => value
.split(|c: char| c.is_ascii_whitespace())
.filter(|s| !s.is_empty())
.map(|o| vm.ctx.new_str(o.to_string()))
.map(|o| vm.ctx.new_str(o.to_owned()))
.collect(),
(None, false) => value
.splitn(num_splits as usize + 1, |c: char| c.is_ascii_whitespace())
.filter(|s| !s.is_empty())
.map(|o| vm.ctx.new_str(o.to_string()))
.map(|o| vm.ctx.new_str(o.to_owned()))
.collect(),
};
vm.ctx.new_list(elements)
@@ -446,21 +447,21 @@ impl PyString {
let mut elements: Vec<_> = match (pattern, num_splits.is_negative()) {
(Some(pattern), true) => value
.rsplit(pattern)
.map(|o| vm.ctx.new_str(o.to_string()))
.map(|o| vm.ctx.new_str(o.to_owned()))
.collect(),
(Some(pattern), false) => value
.rsplitn(num_splits as usize + 1, pattern)
.map(|o| vm.ctx.new_str(o.to_string()))
.map(|o| vm.ctx.new_str(o.to_owned()))
.collect(),
(None, true) => value
.rsplit(|c: char| c.is_ascii_whitespace())
.filter(|s| !s.is_empty())
.map(|o| vm.ctx.new_str(o.to_string()))
.map(|o| vm.ctx.new_str(o.to_owned()))
.collect(),
(None, false) => value
.rsplitn(num_splits as usize + 1, |c: char| c.is_ascii_whitespace())
.filter(|s| !s.is_empty())
.map(|o| vm.ctx.new_str(o.to_string()))
.map(|o| vm.ctx.new_str(o.to_owned()))
.collect(),
};
// Unlike Python rsplit, Rust rsplitn returns an iterator that
@@ -470,34 +471,34 @@ impl PyString {
}
#[pymethod]
fn strip(&self, chars: OptionalArg<PyStringRef>, _vm: &VirtualMachine) -> String {
fn strip(&self, chars: OptionalArg<PyStringRef>) -> String {
let chars = match chars {
OptionalArg::Present(ref chars) => &chars.value,
OptionalArg::Missing => return self.value.trim().to_string(),
OptionalArg::Missing => return self.value.trim().to_owned(),
};
self.value.trim_matches(|c| chars.contains(c)).to_string()
self.value.trim_matches(|c| chars.contains(c)).to_owned()
}
#[pymethod]
fn lstrip(&self, chars: OptionalArg<PyStringRef>, _vm: &VirtualMachine) -> String {
fn lstrip(&self, chars: OptionalArg<PyStringRef>) -> String {
let chars = match chars {
OptionalArg::Present(ref chars) => &chars.value,
OptionalArg::Missing => return self.value.trim_start().to_string(),
OptionalArg::Missing => return self.value.trim_start().to_owned(),
};
self.value
.trim_start_matches(|c| chars.contains(c))
.to_string()
.to_owned()
}
#[pymethod]
fn rstrip(&self, chars: OptionalArg<PyStringRef>, _vm: &VirtualMachine) -> String {
fn rstrip(&self, chars: OptionalArg<PyStringRef>) -> String {
let chars = match chars {
OptionalArg::Present(ref chars) => &chars.value,
OptionalArg::Missing => return self.value.trim_end().to_string(),
OptionalArg::Missing => return self.value.trim_end().to_owned(),
};
self.value
.trim_end_matches(|c| chars.contains(c))
.to_string()
.to_owned()
}
#[pymethod]
@@ -553,17 +554,17 @@ impl PyString {
}
#[pymethod]
fn isalnum(&self, _vm: &VirtualMachine) -> bool {
fn isalnum(&self) -> bool {
!self.value.is_empty() && self.value.chars().all(char::is_alphanumeric)
}
#[pymethod]
fn isnumeric(&self, _vm: &VirtualMachine) -> bool {
fn isnumeric(&self) -> bool {
!self.value.is_empty() && self.value.chars().all(char::is_numeric)
}
#[pymethod]
fn isdigit(&self, _vm: &VirtualMachine) -> bool {
fn isdigit(&self) -> bool {
// python's isdigit also checks if exponents are digits, these are the unicodes for exponents
let valid_unicodes: [u16; 10] = [
0x2070, 0x00B9, 0x00B2, 0x00B3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079,
@@ -580,7 +581,7 @@ impl PyString {
}
#[pymethod]
fn isdecimal(&self, _vm: &VirtualMachine) -> bool {
fn isdecimal(&self) -> bool {
if self.value.is_empty() {
false
} else {
@@ -605,7 +606,7 @@ impl PyString {
fn format(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
if args.args.is_empty() {
return Err(vm.new_type_error(
"descriptor 'format' of 'str' object needs an argument".to_string(),
"descriptor 'format' of 'str' object needs an argument".to_owned(),
));
}
@@ -623,9 +624,9 @@ impl PyString {
Ok(format_string) => perform_format(vm, &format_string, &args),
Err(err) => match err {
FormatParseError::UnmatchedBracket => {
Err(vm.new_value_error("expected '}' before end of string".to_string()))
Err(vm.new_value_error("expected '}' before end of string".to_owned()))
}
_ => Err(vm.new_value_error("Unexpected error parsing format string".to_string())),
_ => Err(vm.new_value_error("Unexpected error parsing format string".to_owned())),
},
}
}
@@ -649,9 +650,9 @@ impl PyString {
Ok(format_string) => perform_format_map(vm, &format_string, &args.args[1]),
Err(err) => match err {
FormatParseError::UnmatchedBracket => {
Err(vm.new_value_error("expected '}' before end of string".to_string()))
Err(vm.new_value_error("expected '}' before end of string".to_owned()))
}
_ => Err(vm.new_value_error("Unexpected error parsing format string".to_string())),
_ => Err(vm.new_value_error("Unexpected error parsing format string".to_owned())),
},
}
}
@@ -659,7 +660,7 @@ impl PyString {
/// Return a titlecased version of the string where words start with an
/// uppercase character and the remaining characters are lowercase.
#[pymethod]
fn title(&self, _vm: &VirtualMachine) -> String {
fn title(&self) -> String {
let mut title = String::with_capacity(self.value.len());
let mut previous_is_cased = false;
for c in self.value.chars() {
@@ -686,7 +687,7 @@ impl PyString {
}
#[pymethod]
fn swapcase(&self, _vm: &VirtualMachine) -> String {
fn swapcase(&self) -> String {
let mut swapped_str = String::with_capacity(self.value.len());
for c in self.value.chars() {
// to_uppercase returns an iterator, to_ascii_uppercase returns the char
@@ -702,18 +703,12 @@ impl PyString {
}
#[pymethod]
fn isalpha(&self, _vm: &VirtualMachine) -> bool {
fn isalpha(&self) -> bool {
!self.value.is_empty() && self.value.chars().all(char::is_alphanumeric)
}
#[pymethod]
fn replace(
&self,
old: PyStringRef,
new: PyStringRef,
num: OptionalArg<usize>,
_vm: &VirtualMachine,
) -> String {
fn replace(&self, old: PyStringRef, new: PyStringRef, num: OptionalArg<usize>) -> String {
match num.into_option() {
Some(num) => self.value.replacen(&old.value, &new.value, num),
None => self.value.replace(&old.value, &new.value),
@@ -736,7 +731,7 @@ impl PyString {
/// * Zp Separator, Paragraph ('\u2029', PARAGRAPH SEPARATOR)
/// * Zs (Separator, Space) other than ASCII space('\x20').
#[pymethod]
fn isprintable(&self, _vm: &VirtualMachine) -> bool {
fn isprintable(&self) -> bool {
self.value
.chars()
.all(|c| c == '\u{0020}' || char_is_printable(c))
@@ -745,13 +740,13 @@ impl PyString {
// cpython's isspace ignores whitespace, including \t and \n, etc, unless the whole string is empty
// which is why isspace is using is_ascii_whitespace. Same for isupper & islower
#[pymethod]
fn isspace(&self, _vm: &VirtualMachine) -> bool {
fn isspace(&self) -> bool {
!self.value.is_empty() && self.value.chars().all(|c| c.is_ascii_whitespace())
}
// Return true if all cased characters in the string are uppercase and there is at least one cased character, false otherwise.
#[pymethod]
fn isupper(&self, _vm: &VirtualMachine) -> bool {
fn isupper(&self) -> bool {
let mut cased = false;
for c in self.value.chars() {
if is_cased(c) && c.is_uppercase() {
@@ -765,7 +760,7 @@ impl PyString {
// Return true if all cased characters in the string are lowercase and there is at least one cased character, false otherwise.
#[pymethod]
fn islower(&self, _vm: &VirtualMachine) -> bool {
fn islower(&self) -> bool {
let mut cased = false;
for c in self.value.chars() {
if is_cased(c) && c.is_lowercase() {
@@ -778,7 +773,7 @@ impl PyString {
}
#[pymethod]
fn isascii(&self, _vm: &VirtualMachine) -> bool {
fn isascii(&self) -> bool {
!self.value.is_empty() && self.value.chars().all(|c| c.is_ascii())
}
@@ -786,7 +781,7 @@ impl PyString {
fn splitlines(&self, args: SplitLineArgs, vm: &VirtualMachine) -> PyObjectRef {
let keepends = args.keepends.unwrap_or(false);
let mut elements = vec![];
let mut curr = "".to_string();
let mut curr = "".to_owned();
for ch in self.value.chars() {
if ch == '\n' {
if keepends {
@@ -820,13 +815,7 @@ impl PyString {
}
#[pymethod]
fn find(
&self,
sub: PyStringRef,
start: OptionalArg<isize>,
end: OptionalArg<isize>,
_vm: &VirtualMachine,
) -> isize {
fn find(&self, sub: PyStringRef, start: OptionalArg<isize>, end: OptionalArg<isize>) -> isize {
let value = &self.value;
if let Some((start, end)) = adjust_indices(start, end, value.len()) {
match value[start..end].find(&sub.value) {
@@ -839,13 +828,7 @@ impl PyString {
}
#[pymethod]
fn rfind(
&self,
sub: PyStringRef,
start: OptionalArg<isize>,
end: OptionalArg<isize>,
_vm: &VirtualMachine,
) -> isize {
fn rfind(&self, sub: PyStringRef, start: OptionalArg<isize>, end: OptionalArg<isize>) -> isize {
let value = &self.value;
if let Some((start, end)) = adjust_indices(start, end, value.len()) {
match value[start..end].rfind(&sub.value) {
@@ -869,10 +852,10 @@ impl PyString {
if let Some((start, end)) = adjust_indices(start, end, value.len()) {
match value[start..end].find(&sub.value) {
Some(num) => Ok(start + num),
None => Err(vm.new_value_error("substring not found".to_string())),
None => Err(vm.new_value_error("substring not found".to_owned())),
}
} else {
Err(vm.new_value_error("substring not found".to_string()))
Err(vm.new_value_error("substring not found".to_owned()))
}
}
@@ -888,10 +871,10 @@ impl PyString {
if let Some((start, end)) = adjust_indices(start, end, value.len()) {
match value[start..end].rfind(&sub.value) {
Some(num) => Ok(start + num),
None => Err(vm.new_value_error("substring not found".to_string())),
None => Err(vm.new_value_error("substring not found".to_owned())),
}
} else {
Err(vm.new_value_error("substring not found".to_string()))
Err(vm.new_value_error("substring not found".to_owned()))
}
}
@@ -903,13 +886,13 @@ impl PyString {
if value.contains(sub) {
new_tup = value
.splitn(2, sub)
.map(|s| vm.ctx.new_str(s.to_string()))
.map(|s| vm.ctx.new_str(s.to_owned()))
.collect();
new_tup.insert(1, vm.ctx.new_str(sub.clone()));
} else {
new_tup.push(vm.ctx.new_str(value.clone()));
new_tup.push(vm.ctx.new_str("".to_string()));
new_tup.push(vm.ctx.new_str("".to_string()));
new_tup.push(vm.ctx.new_str("".to_owned()));
new_tup.push(vm.ctx.new_str("".to_owned()));
}
vm.ctx.new_tuple(new_tup)
}
@@ -922,13 +905,13 @@ impl PyString {
if value.contains(sub) {
new_tup = value
.rsplitn(2, sub)
.map(|s| vm.ctx.new_str(s.to_string()))
.map(|s| vm.ctx.new_str(s.to_owned()))
.collect();
new_tup.swap(0, 1); // so it's in the right order
new_tup.insert(1, vm.ctx.new_str(sub.clone()));
} else {
new_tup.push(vm.ctx.new_str("".to_string()));
new_tup.push(vm.ctx.new_str("".to_string()));
new_tup.push(vm.ctx.new_str("".to_owned()));
new_tup.push(vm.ctx.new_str("".to_owned()));
new_tup.push(vm.ctx.new_str(value.clone()));
}
vm.ctx.new_tuple(new_tup)
@@ -937,7 +920,7 @@ impl PyString {
/// Return `true` if the sequence is ASCII titlecase and the sequence is not
/// empty, `false` otherwise.
#[pymethod]
fn istitle(&self, _vm: &VirtualMachine) -> bool {
fn istitle(&self) -> bool {
if self.value.is_empty() {
return false;
}
@@ -965,13 +948,7 @@ impl PyString {
}
#[pymethod]
fn count(
&self,
sub: PyStringRef,
start: OptionalArg<isize>,
end: OptionalArg<isize>,
_vm: &VirtualMachine,
) -> usize {
fn count(&self, sub: PyStringRef, start: OptionalArg<isize>, end: OptionalArg<isize>) -> usize {
let value = &self.value;
if let Some((start, end)) = adjust_indices(start, end, value.len()) {
self.value[start..end].matches(&sub.value).count()
@@ -981,10 +958,10 @@ impl PyString {
}
#[pymethod]
fn zfill(&self, len: usize, _vm: &VirtualMachine) -> String {
fn zfill(&self, len: usize) -> String {
let value = &self.value;
if len <= value.len() {
value.to_string()
value.to_owned()
} else {
format!("{}{}", "0".repeat(len - value.len()), value)
}
@@ -1001,9 +978,8 @@ impl PyString {
if rep_str.len() == 1 {
Ok(rep_str)
} else {
Err(vm.new_type_error(
"The fill character must be exactly one character long".to_string(),
))
Err(vm
.new_type_error("The fill character must be exactly one character long".to_owned()))
}
}
@@ -1017,7 +993,7 @@ impl PyString {
let value = &self.value;
let rep_char = Self::get_fill_char(&rep, vm)?;
if len <= value.len() {
Ok(value.to_string())
Ok(value.to_owned())
} else {
Ok(format!("{}{}", value, rep_char.repeat(len - value.len())))
}
@@ -1033,7 +1009,7 @@ impl PyString {
let value = &self.value;
let rep_char = Self::get_fill_char(&rep, vm)?;
if len <= value.len() {
Ok(value.to_string())
Ok(value.to_owned())
} else {
Ok(format!("{}{}", rep_char.repeat(len - value.len()), value))
}
@@ -1051,7 +1027,7 @@ impl PyString {
let value_len = self.value.chars().count();
if len <= value_len {
return Ok(value.to_string());
return Ok(value.to_owned());
}
let diff: usize = len - value_len;
let mut left_buff: usize = diff / 2;
@@ -1073,7 +1049,7 @@ impl PyString {
}
#[pymethod]
fn expandtabs(&self, tab_stop: OptionalArg<usize>, _vm: &VirtualMachine) -> String {
fn expandtabs(&self, tab_stop: OptionalArg<usize>) -> String {
let tab_stop = tab_stop.into_option().unwrap_or(8 as usize);
let mut expanded_str = String::with_capacity(self.value.len());
let mut tab_size = tab_stop;
@@ -1097,7 +1073,7 @@ impl PyString {
}
#[pymethod]
fn isidentifier(&self, _vm: &VirtualMachine) -> bool {
fn isidentifier(&self) -> bool {
let mut chars = self.value.chars();
let is_identifier_start = chars.next().map_or(false, |c| c == '_' || is_xid_start(c));
// a string is not an identifier if it has whitespace or starts with a number
@@ -1151,7 +1127,7 @@ impl PyString {
if let OptionalArg::Present(to_str) = to_str {
match dict_or_str.downcast::<PyString>() {
Ok(from_str) => {
if to_str.len(vm) == from_str.len(vm) {
if to_str.len() == from_str.len() {
for (c1, c2) in from_str.value.chars().zip(to_str.value.chars()) {
new_dict.set_item(&vm.new_int(c1 as u32), vm.new_int(c2 as u32), vm)?;
}
@@ -1184,7 +1160,7 @@ impl PyString {
vm,
)?;
} else if let Some(string) = key.payload::<PyString>() {
if string.len(vm) == 1 {
if string.len() == 1 {
let num_value = string.value.chars().next().unwrap() as u32;
new_dict.set_item(&num_value.into_pyobject(vm)?, val, vm)?;
} else {
@@ -1214,7 +1190,7 @@ impl PyString {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyStringIterator {
fn iter(zelf: PyRef<Self>) -> PyStringIterator {
PyStringIterator {
byte_position: Cell::new(0),
string: zelf,
@@ -1222,7 +1198,7 @@ impl PyString {
}
#[pymethod(name = "__reversed__")]
fn reversed(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyStringReverseIterator {
fn reversed(zelf: PyRef<Self>) -> PyStringReverseIterator {
let begin = zelf.value.chars().count();
PyStringReverseIterator {
@@ -1264,7 +1240,7 @@ impl IntoPyObject for String {
impl IntoPyObject for &str {
fn into_pyobject(self, vm: &VirtualMachine) -> PyResult {
Ok(vm.ctx.new_str(self.to_string()))
Ok(vm.ctx.new_str(self.to_owned()))
}
}
@@ -1314,7 +1290,7 @@ fn call_object_format(vm: &VirtualMachine, argument: PyObjectRef, format_spec: &
Some(FormatPreconversor::Bytes) => vm.call_method(&argument, "decode", vec![])?,
None => argument,
};
let returned_type = vm.ctx.new_str(new_format_spec.to_string());
let returned_type = vm.ctx.new_str(new_format_spec.to_owned());
let result = vm.call_method(&argument, "__format__", vec![returned_type])?;
if !objtype::isinstance(&result, &vm.ctx.str_type()) {
@@ -1381,20 +1357,20 @@ fn do_cformat_specifier(
match objint::get_value(&obj).to_u32().and_then(char::from_u32) {
Some(value) => Ok(value.to_string()),
None => {
Err(vm.new_overflow_error("%c arg not in range(0x110000)".to_string()))
Err(vm.new_overflow_error("%c arg not in range(0x110000)".to_owned()))
}
}
} else if objtype::isinstance(&obj, &vm.ctx.str_type()) {
let s = borrow_value(&obj);
let num_chars = s.chars().count();
if num_chars != 1 {
Err(vm.new_type_error("%c requires int or char".to_string()))
Err(vm.new_type_error("%c requires int or char".to_owned()))
} else {
Ok(s.chars().next().unwrap().to_string())
}
} else {
// TODO re-arrange this block so this error is only created once
Err(vm.new_type_error("%c requires int or char".to_string()))
Err(vm.new_type_error("%c requires int or char".to_owned()))
}
}?;
format_spec.precision = Some(CFormatQuantity::Amount(1));
@@ -1415,7 +1391,7 @@ fn try_update_quantity_from_tuple(
Some(width_obj) => {
tuple_index += 1;
if !objtype::isinstance(&width_obj, &vm.ctx.int_type()) {
Err(vm.new_type_error("* wants int".to_string()))
Err(vm.new_type_error("* wants int".to_owned()))
} else {
// TODO: handle errors when truncating BigInt to usize
*q = Some(CFormatQuantity::Amount(
@@ -1424,9 +1400,7 @@ fn try_update_quantity_from_tuple(
Ok(tuple_index)
}
}
None => {
Err(vm.new_type_error("not enough arguments for format string".to_string()))
}
None => Err(vm.new_type_error("not enough arguments for format string".to_owned())),
}
}
_ => Ok(tuple_index),
@@ -1456,7 +1430,7 @@ pub fn do_cformat_string(
let values = if mapping_required {
if !objtype::isinstance(&values_obj, &vm.ctx.dict_type()) {
return Err(vm.new_type_error("format requires a mapping".to_string()));
return Err(vm.new_type_error("format requires a mapping".to_owned()));
}
values_obj.clone()
} else {
@@ -1467,7 +1441,7 @@ pub fn do_cformat_string(
&& !objtype::isinstance(&values_obj, &vm.ctx.types.dict_type)
{
return Err(vm.new_type_error(
"not all arguments converted during string formatting".to_string(),
"not all arguments converted during string formatting".to_owned(),
));
}
@@ -1487,7 +1461,7 @@ pub fn do_cformat_string(
let obj: PyObjectRef = match &format_spec.mapping_key {
Some(key) => {
// TODO: change the KeyError message to match the one in cpython
call_getitem(vm, &values, &vm.ctx.new_str(key.to_string()))?
call_getitem(vm, &values, &vm.ctx.new_str(key.to_owned()))?
}
None => {
let mut elements = objtuple::get_value(&values)
@@ -1511,7 +1485,7 @@ pub fn do_cformat_string(
let obj = match elements.next() {
Some(obj) => Ok(obj),
None => Err(vm.new_type_error(
"not enough arguments for format string".to_string(),
"not enough arguments for format string".to_owned(),
)),
}?;
tuple_index += 1;
@@ -1531,7 +1505,7 @@ pub fn do_cformat_string(
&& !objtype::isinstance(&values_obj, &vm.ctx.types.dict_type)
{
return Err(
vm.new_type_error("not all arguments converted during string formatting".to_string())
vm.new_type_error("not all arguments converted during string formatting".to_owned())
);
}
Ok(final_string)
@@ -1557,8 +1531,7 @@ fn perform_format(
&& format_string.format_parts.iter().any(FormatPart::is_index)
{
return Err(vm.new_value_error(
"cannot switch from automatic field numbering to manual field specification"
.to_string(),
"cannot switch from automatic field numbering to manual field specification".to_owned(),
));
}
let mut auto_argument_index: usize = 1;
@@ -1568,7 +1541,7 @@ fn perform_format(
let result = match arguments.args.get(auto_argument_index) {
Some(argument) => call_object_format(vm, argument.clone(), &format_spec)?,
None => {
return Err(vm.new_index_error("tuple index out of range".to_string()));
return Err(vm.new_index_error("tuple index out of range".to_owned()));
}
};
auto_argument_index += 1;
@@ -1578,7 +1551,7 @@ fn perform_format(
let result = match arguments.args.get(*index + 1) {
Some(argument) => call_object_format(vm, argument.clone(), &format_spec)?,
None => {
return Err(vm.new_index_error("tuple index out of range".to_string()));
return Err(vm.new_index_error("tuple index out of range".to_owned()));
}
};
clone_value(&result)
@@ -1587,7 +1560,7 @@ fn perform_format(
let result = match arguments.get_optional_kwarg(&keyword) {
Some(argument) => call_object_format(vm, argument.clone(), &format_spec)?,
None => {
return Err(vm.new_key_error(vm.new_str(keyword.to_string())));
return Err(vm.new_key_error(vm.new_str(keyword.to_owned())));
}
};
clone_value(&result)
@@ -1609,7 +1582,7 @@ fn perform_format_map(
let result_string: String = match part {
FormatPart::AutoSpec(_) | FormatPart::IndexSpec(_, _) => {
return Err(
vm.new_value_error("Format string contains positional fields".to_string())
vm.new_value_error("Format string contains positional fields".to_owned())
);
}
FormatPart::KeywordSpec(keyword, format_spec) => {
@@ -1738,7 +1711,7 @@ mod tests {
("Greek ῼitlecases ...", "greek ῳitlecases ..."),
];
for (title, input) in tests {
assert_eq!(PyString::from(input).title(&vm).as_str(), title);
assert_eq!(PyString::from(input).title().as_str(), title);
}
}
@@ -1756,7 +1729,7 @@ mod tests {
];
for s in pos {
assert!(PyString::from(s).istitle(&vm));
assert!(PyString::from(s).istitle());
}
let neg = vec![
@@ -1769,7 +1742,7 @@ mod tests {
"NOT",
];
for s in neg {
assert!(!PyString::from(s).istitle(&vm));
assert!(!PyString::from(s).istitle());
}
}

View File

@@ -35,11 +35,11 @@ impl PyValue for PySuper {
#[pyimpl]
impl PySuper {
#[pymethod(name = "__repr__")]
fn repr(&self, _vm: &VirtualMachine) -> String {
fn repr(&self) -> String {
let class_type_str = if let Ok(type_class) = self.typ.clone().downcast::<PyClass>() {
type_class.name.clone()
} else {
"NONE".to_string()
"NONE".to_owned()
};
match self.obj_type.clone().downcast::<PyClass>() {
Ok(obj_class_typ) => format!(
@@ -63,7 +63,7 @@ impl PySuper {
// This is a classmethod
return Ok(item);
}
return vm.call_get_descriptor(item, inst.clone());
return vm.call_if_get_descriptor(item, inst.clone());
}
}
Err(vm.new_attribute_error(format!(
@@ -92,7 +92,7 @@ impl PySuper {
_ => {
return Err(vm.new_type_error(
"super must be called with 1 argument or from inside class method"
.to_string(),
.to_owned(),
));
}
}
@@ -123,7 +123,7 @@ impl PySuper {
}
} else {
return Err(vm.new_type_error(
"super must be called with 1 argument or from inside class method".to_string(),
"super must be called with 1 argument or from inside class method".to_owned(),
));
}
};
@@ -137,7 +137,7 @@ impl PySuper {
};
if !is_subclass {
return Err(vm.new_type_error(
"super(type, obj): obj must be an instance or subtype of type".to_string(),
"super(type, obj): obj must be an instance or subtype of type".to_owned(),
));
}
PyClassRef::try_from_object(vm, py_obj.clone())?
@@ -172,6 +172,6 @@ pub fn init(context: &PyContext) {
super().cmeth(arg)\n";
extend_class!(context, super_type, {
"__doc__" => context.new_str(super_doc.to_string()),
"__doc__" => context.new_str(super_doc.to_owned()),
});
}

View File

@@ -32,22 +32,22 @@ impl PyTraceback {
}
#[pyproperty(name = "tb_frame")]
fn frame(&self, _vm: &VirtualMachine) -> FrameRef {
fn frame(&self) -> FrameRef {
self.frame.clone()
}
#[pyproperty(name = "tb_lasti")]
fn lasti(&self, _vm: &VirtualMachine) -> usize {
fn lasti(&self) -> usize {
self.lasti
}
#[pyproperty(name = "tb_lineno")]
fn lineno(&self, _vm: &VirtualMachine) -> usize {
fn lineno(&self) -> usize {
self.lineno
}
#[pyproperty(name = "tb_next")]
fn next_get(&self, _vm: &VirtualMachine) -> Option<PyTracebackRef> {
fn next_get(&self) -> Option<PyTracebackRef> {
self.next.as_ref().cloned()
}
}

View File

@@ -127,7 +127,7 @@ impl PyTuple {
}
#[pymethod(name = "__bool__")]
fn bool(&self, _vm: &VirtualMachine) -> bool {
fn bool(&self) -> bool {
!self.elements.is_empty()
}
@@ -158,7 +158,7 @@ impl PyTuple {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyTupleIterator {
fn iter(zelf: PyRef<Self>) -> PyTupleIterator {
PyTupleIterator {
position: Cell::new(0),
tuple: zelf,
@@ -166,7 +166,7 @@ impl PyTuple {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.elements.len()
}
@@ -185,24 +185,20 @@ impl PyTuple {
format!("({})", str_parts.join(", "))
}
} else {
"(...)".to_string()
"(...)".to_owned()
};
Ok(s)
}
#[pymethod(name = "__mul__")]
fn mul(&self, counter: isize, _vm: &VirtualMachine) -> PyTuple {
#[pymethod(name = "__rmul__")]
fn mul(&self, counter: isize) -> PyTuple {
let new_elements: Vec<_> = sequence::seq_mul(&self.elements, counter)
.cloned()
.collect();
new_elements.into()
}
#[pymethod(name = "__rmul__")]
fn rmul(&self, counter: isize, vm: &VirtualMachine) -> PyTuple {
self.mul(counter, vm)
}
#[pymethod(name = "__getitem__")]
fn getitem(zelf: PyRef<Self>, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
get_item(vm, zelf.as_object(), &zelf.elements, needle.clone())
@@ -215,7 +211,7 @@ impl PyTuple {
return Ok(index);
}
}
Err(vm.new_value_error("tuple.index(x): x not in tuple".to_string()))
Err(vm.new_value_error("tuple.index(x): x not in tuple".to_owned()))
}
#[pymethod(name = "__contains__")]
@@ -271,7 +267,7 @@ impl PyTupleIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -5,11 +5,10 @@ use std::fmt;
use super::objdict::PyDictRef;
use super::objlist::PyList;
use super::objmappingproxy::PyMappingProxy;
use super::objproperty::PropertyBuilder;
use super::objstr::PyStringRef;
use super::objtuple::PyTuple;
use super::objweakref::PyWeak;
use crate::function::PyFuncArgs;
use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{
IdProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable, PyObject, PyObjectRef, PyRef,
PyResult, PyValue, TypeProtocol,
@@ -80,16 +79,13 @@ impl PyClassRef {
}
}
fn _mro(self, _vm: &VirtualMachine) -> PyTuple {
#[pyproperty(name = "__mro__")]
fn get_mro(self) -> PyTuple {
let elements: Vec<PyObjectRef> =
_mro(&self).iter().map(|x| x.as_object().clone()).collect();
PyTuple::from(elements)
}
fn _set_mro(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_attribute_error("read-only attribute".to_string()))
}
#[pyproperty(magic)]
fn bases(self, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx
@@ -101,28 +97,28 @@ impl PyClassRef {
let attributes = self.get_attributes();
let attributes: Vec<PyObjectRef> = attributes
.keys()
.map(|k| vm.ctx.new_str(k.to_string()))
.map(|k| vm.ctx.new_str(k.to_owned()))
.collect();
PyList::from(attributes)
}
#[pymethod(magic)]
fn instancecheck(self, obj: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn instancecheck(self, obj: PyObjectRef) -> bool {
isinstance(&obj, &self)
}
#[pymethod(magic)]
fn subclasscheck(self, subclass: PyClassRef, _vm: &VirtualMachine) -> bool {
fn subclasscheck(self, subclass: PyClassRef) -> bool {
issubclass(&subclass, &self)
}
#[pyproperty(magic)]
fn name(self, _vm: &VirtualMachine) -> String {
fn name(self) -> String {
self.name.clone()
}
#[pymethod(magic)]
fn repr(self, _vm: &VirtualMachine) -> String {
fn repr(self) -> String {
format!("<class '{}'>", self.name)
}
@@ -145,6 +141,13 @@ impl PyClassRef {
.unwrap_or_else(|| vm.ctx.new_str("builtins".to_owned()))
}
#[pyproperty(magic, setter)]
fn set_module(self, value: PyObjectRef) {
self.attributes
.borrow_mut()
.insert("__module__".to_owned(), value);
}
#[pymethod(magic)]
fn prepare(_name: PyStringRef, _bases: PyObjectRef, vm: &VirtualMachine) -> PyDictRef {
vm.ctx.new_dict()
@@ -170,7 +173,11 @@ impl PyClassRef {
if let Some(attr) = self.get_attr(&name) {
let attr_class = attr.class();
if let Some(ref descriptor) = attr_class.get_attr("__get__") {
let slots = attr_class.slots.borrow();
if let Some(ref descr_get) = slots.descr_get {
return descr_get(vm, attr, None, OptionalArg::Present(self.into_object()));
} else if let Some(ref descriptor) = attr_class.get_attr("__get__") {
// TODO: is this nessessary?
return vm.invoke(descriptor, vec![attr, vm.get_none(), self.into_object()]);
}
}
@@ -178,7 +185,7 @@ impl PyClassRef {
if let Some(cls_attr) = self.get_attr(&name) {
Ok(cls_attr)
} else if let Some(attr) = mcl.get_attr(&name) {
vm.call_get_descriptor(attr, self.into_object())
vm.call_if_get_descriptor(attr, self.into_object())
} else if let Some(ref getter) = self.get_attr("__getattr__") {
vm.invoke(getter, vec![mcl.into_object(), name_ref.into_object()])
} else {
@@ -220,7 +227,7 @@ impl PyClassRef {
self.attributes.borrow_mut().remove(attr_name.as_str());
Ok(())
} else {
Err(vm.new_attribute_error(attr_name.as_str().to_string()))
Err(vm.new_attribute_error(attr_name.as_str().to_owned()))
}
}
@@ -228,11 +235,11 @@ impl PyClassRef {
pub fn set_str_attr<V: Into<PyObjectRef>>(&self, attr_name: &str, value: V) {
self.attributes
.borrow_mut()
.insert(attr_name.to_string(), value.into());
.insert(attr_name.to_owned(), value.into());
}
#[pymethod(magic)]
fn subclasses(self, _vm: &VirtualMachine) -> PyList {
fn subclasses(self) -> PyList {
let mut subclasses = self.subclasses.borrow_mut();
subclasses.retain(|x| x.upgrade().is_some());
PyList::from(
@@ -261,7 +268,7 @@ impl PyClassRef {
if args.args.len() != 3 {
return Err(vm.new_type_error(if is_type_type {
"type() takes 1 or 3 arguments".to_string()
"type() takes 1 or 3 arguments".to_owned()
} else {
format!(
"type.__new__() takes exactly 3 arguments ({} given)",
@@ -322,11 +329,23 @@ impl PyClassRef {
let init_method = init_method_or_err?;
let res = vm.invoke(&init_method, args)?;
if !res.is(&vm.get_none()) {
return Err(vm.new_type_error("__init__ must return None".to_string()));
return Err(vm.new_type_error("__init__ must return None".to_owned()));
}
}
Ok(obj)
}
#[pyproperty(magic)]
fn dict(self) -> PyMappingProxy {
PyMappingProxy::new(self)
}
#[pyproperty(magic, setter)]
fn set_dict(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_not_implemented_error(
"Setting __dict__ attribute on a type isn't yet implemented".to_owned(),
))
}
}
/*
@@ -335,18 +354,6 @@ impl PyClassRef {
pub(crate) fn init(ctx: &PyContext) {
PyClassRef::extend_class(ctx, &ctx.types.type_type);
extend_class!(&ctx, &ctx.types.type_type, {
"__dict__" =>
PropertyBuilder::new(ctx)
.add_getter(type_dict)
.add_setter(type_dict_setter)
.create(),
"__mro__" =>
PropertyBuilder::new(ctx)
.add_getter(PyClassRef::_mro)
.add_setter(PyClassRef::_set_mro)
.create(),
});
}
fn _mro(cls: &PyClassRef) -> Vec<PyClassRef> {
@@ -398,20 +405,6 @@ pub fn type_new(
new(vm, args.insert(cls.into_object()))
}
fn type_dict(class: PyClassRef, _vm: &VirtualMachine) -> PyMappingProxy {
PyMappingProxy::new(class)
}
fn type_dict_setter(
_instance: PyClassRef,
_value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Err(vm.new_not_implemented_error(
"Setting __dict__ attribute on a type isn't yet implemented".to_string(),
))
}
impl PyClassRef {
/// This is the internal get_attr implementation for fast lookup on a class.
pub fn get_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
@@ -448,7 +441,7 @@ impl PyClassRef {
for bc in base_classes {
for (name, value) in bc.attributes.borrow().iter() {
attributes.insert(name.to_string(), value.clone());
attributes.insert(name.to_owned(), value.clone());
}
}
@@ -548,7 +541,7 @@ fn calculate_meta_class(
return Err(vm.new_type_error(
"metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass \
of the metaclasses of all its bases"
.to_string(),
.to_owned(),
));
}
Ok(winner)

View File

@@ -43,7 +43,7 @@ impl PyWeakProxy {
Some(obj) => vm.get_attribute(obj, attr_name),
None => Err(vm.new_exception_msg(
vm.ctx.exceptions.reference_error.clone(),
"weakly-referenced object no longer exists".to_string(),
"weakly-referenced object no longer exists".to_owned(),
)),
}
}
@@ -54,7 +54,7 @@ impl PyWeakProxy {
Some(obj) => vm.set_attr(&obj, attr_name, value),
None => Err(vm.new_exception_msg(
vm.ctx.exceptions.reference_error.clone(),
"weakly-referenced object no longer exists".to_string(),
"weakly-referenced object no longer exists".to_owned(),
)),
}
}

View File

@@ -3,7 +3,7 @@ use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{
PyClassImpl, PyContext, PyObject, PyObjectPayload, PyObjectRef, PyRef, PyResult, PyValue,
};
use crate::slots::PyBuiltinCallable;
use crate::slots::SlotCall;
use crate::vm::VirtualMachine;
use std::rc::{Rc, Weak};
@@ -34,14 +34,14 @@ impl PyValue for PyWeak {
pub type PyWeakRef = PyRef<PyWeak>;
impl PyBuiltinCallable for PyWeak {
impl SlotCall for PyWeak {
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
args.bind::<()>(vm)?;
Ok(self.referent.upgrade().unwrap_or_else(|| vm.get_none()))
}
}
#[pyimpl(with(PyBuiltinCallable), flags(BASETYPE))]
#[pyimpl(with(SlotCall), flags(BASETYPE))]
impl PyWeak {
// TODO callbacks
#[pyslot]

View File

@@ -45,7 +45,7 @@ impl PyZip {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -176,7 +176,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
E: serde::de::Error,
{
// Owned value needed anyway, delegate to visit_string
self.visit_string(value.to_string())
self.visit_string(value.to_owned())
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>

View File

@@ -25,13 +25,13 @@ use crate::obj::objcomplex::PyComplex;
use crate::obj::objdict::{PyDict, PyDictRef};
use crate::obj::objfloat::PyFloat;
use crate::obj::objfunction::{PyBoundMethod, PyFunction};
use crate::obj::objgetset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet};
use crate::obj::objint::{PyInt, PyIntRef};
use crate::obj::objiter;
use crate::obj::objlist::PyList;
use crate::obj::objnamespace::PyNamespace;
use crate::obj::objnone::{PyNone, PyNoneRef};
use crate::obj::objobject;
use crate::obj::objproperty::PropertyBuilder;
use crate::obj::objset::PySet;
use crate::obj::objstr;
use crate::obj::objtuple::{PyTuple, PyTupleRef};
@@ -330,6 +330,10 @@ impl PyContext {
self.types.readonly_property_type.clone()
}
pub fn getset_type(&self) -> PyClassRef {
self.types.getset_type.clone()
}
pub fn classmethod_type(&self) -> PyClassRef {
self.types.classmethod_type.clone()
}
@@ -499,11 +503,23 @@ impl PyContext {
)
}
pub fn new_property<F, I, V, VM>(&self, f: F) -> PyObjectRef
pub fn new_readonly_getset<F, T>(&self, name: impl Into<String>, f: F) -> PyObjectRef
where
F: IntoPyNativeFunc<I, V, VM>,
F: IntoPyGetterFunc<T>,
{
PropertyBuilder::new(self).add_getter(f).create()
PyObject::new(PyGetSet::with_get(name.into(), f), self.getset_type(), None)
}
pub fn new_getset<G, S, T, U>(&self, name: impl Into<String>, g: G, s: S) -> PyObjectRef
where
G: IntoPyGetterFunc<T>,
S: IntoPySetterFunc<U>,
{
PyObject::new(
PyGetSet::with_get_set(name.into(), g, s),
self.getset_type(),
None,
)
}
pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyCodeRef {

View File

@@ -1,5 +1,5 @@
use crate::function::{OptionalArg, PyFuncArgs, PyNativeFunc};
use crate::pyobject::{IdProtocol, PyObjectRef, PyRef, PyResult, PyValue};
use crate::pyobject::{IdProtocol, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject};
use crate::VirtualMachine;
bitflags! {
@@ -28,7 +28,7 @@ pub struct PyClassSlots {
pub flags: PyTpFlags,
pub new: Option<PyNativeFunc>,
pub call: Option<PyNativeFunc>,
pub descr_get: Option<PyNativeFunc>,
pub descr_get: Option<PyDescrGetFunc>,
}
impl std::fmt::Debug for PyClassSlots {
@@ -38,22 +38,73 @@ impl std::fmt::Debug for PyClassSlots {
}
#[pyimpl]
pub trait PyBuiltinCallable: PyValue {
pub trait SlotCall: PyValue {
#[pymethod(magic)]
#[pyslot]
fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult;
}
pub type PyDescrGetFunc = Box<
dyn Fn(&VirtualMachine, PyObjectRef, Option<PyObjectRef>, OptionalArg<PyObjectRef>) -> PyResult,
>;
#[pyimpl]
pub trait PyBuiltinDescriptor: PyValue {
pub trait SlotDescriptor: PyValue {
#[pyslot]
fn descr_get(
vm: &VirtualMachine,
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
cls: OptionalArg<PyObjectRef>,
) -> PyResult;
#[pymethod(magic)]
#[pyslot(descr_get)]
fn get(
zelf: PyRef<Self>,
zelf: PyObjectRef,
obj: PyObjectRef,
cls: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult;
) -> PyResult {
Self::descr_get(vm, zelf, Some(obj), cls)
}
fn _zelf(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
PyRef::<Self>::try_from_object(vm, zelf)
}
fn _unwrap(
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<(PyRef<Self>, PyObjectRef)> {
let zelf = Self::_zelf(zelf, vm)?;
let obj = obj.unwrap_or_else(|| vm.get_none());
Ok((zelf, obj))
}
fn _check(
zelf: PyObjectRef,
obj: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> Result<(PyRef<Self>, PyObjectRef), PyResult> {
// CPython descr_check
if let Some(obj) = obj {
// if (!PyObject_TypeCheck(obj, descr->d_type)) {
// PyErr_Format(PyExc_TypeError,
// "descriptor '%V' for '%.100s' objects "
// "doesn't apply to a '%.100s' object",
// descr_name((PyDescrObject *)descr), "?",
// descr->d_type->tp_name,
// obj->ob_type->tp_name);
// *pres = NULL;
// return 1;
// } else {
Ok((Self::_zelf(zelf, vm).unwrap(), obj))
// }
} else {
Err(Ok(zelf))
}
}
fn _cls_is<T>(cls: &OptionalArg<PyObjectRef>, other: &T) -> bool
where

View File

@@ -217,12 +217,12 @@ impl PyArray {
}
#[pyproperty]
fn typecode(&self, _vm: &VirtualMachine) -> String {
fn typecode(&self) -> String {
self.array.borrow().typecode().to_string()
}
#[pyproperty]
fn itemsize(&self, _vm: &VirtualMachine) -> usize {
fn itemsize(&self) -> usize {
self.array.borrow().itemsize()
}
@@ -232,7 +232,7 @@ impl PyArray {
}
#[pymethod]
fn buffer_info(&self, _vm: &VirtualMachine) -> (usize, usize) {
fn buffer_info(&self) -> (usize, usize) {
let array = self.array.borrow();
(array.addr(), array.len())
}
@@ -301,7 +301,7 @@ impl PyArray {
}
#[pymethod]
fn tobytes(&self, _vm: &VirtualMachine) -> Vec<u8> {
fn tobytes(&self) -> Vec<u8> {
self.array.borrow().tobytes()
}
@@ -316,7 +316,7 @@ impl PyArray {
}
#[pymethod]
fn reverse(&self, _vm: &VirtualMachine) {
fn reverse(&self) {
self.array.borrow_mut().reverse()
}
@@ -349,12 +349,12 @@ impl PyArray {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.array.borrow().len()
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyArrayIter {
fn iter(zelf: PyRef<Self>) -> PyArrayIter {
PyArrayIter {
position: Cell::new(0),
array: zelf,
@@ -394,7 +394,7 @@ impl PyArrayIter {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -35,7 +35,7 @@ macro_rules! node {
$(
let field_name = stringify!($attr_name);
$vm.set_attr(node.as_object(), field_name, $attr_value)?;
field_names.push($vm.ctx.new_str(field_name.to_string()));
field_names.push($vm.ctx.new_str(field_name.to_owned()));
)*
$vm.set_attr(node.as_object(), "_fields", $vm.ctx.new_tuple(field_names))?;
node
@@ -81,7 +81,7 @@ fn statement_to_ast(vm: &VirtualMachine, statement: &ast::Statement) -> PyResult
decorator_list,
..
} => node!(vm, ClassDef, {
name => vm.ctx.new_str(name.to_string()),
name => vm.ctx.new_str(name.to_owned()),
keywords => map_ast(keyword_to_ast, vm, keywords)?,
body => statements_to_ast(vm, body)?,
decorator_list => expressions_to_ast(vm, decorator_list)?,
@@ -96,7 +96,7 @@ fn statement_to_ast(vm: &VirtualMachine, statement: &ast::Statement) -> PyResult
} => {
if *is_async {
node!(vm, AsyncFunctionDef, {
name => vm.ctx.new_str(name.to_string()),
name => vm.ctx.new_str(name.to_owned()),
args => parameters_to_ast(vm, args)?,
body => statements_to_ast(vm, body)?,
decorator_list => expressions_to_ast(vm, decorator_list)?,
@@ -104,7 +104,7 @@ fn statement_to_ast(vm: &VirtualMachine, statement: &ast::Statement) -> PyResult
})
} else {
node!(vm, FunctionDef, {
name => vm.ctx.new_str(name.to_string()),
name => vm.ctx.new_str(name.to_owned()),
args => parameters_to_ast(vm, args)?,
body => statements_to_ast(vm, body)?,
decorator_list => expressions_to_ast(vm, decorator_list)?,
@@ -245,7 +245,7 @@ fn statement_to_ast(vm: &VirtualMachine, statement: &ast::Statement) -> PyResult
fn alias_to_ast(vm: &VirtualMachine, alias: &ast::ImportSymbol) -> PyResult<AstNodeRef> {
Ok(node!(vm, alias, {
name => vm.ctx.new_str(alias.symbol.to_string()),
name => vm.ctx.new_str(alias.symbol.to_owned()),
asname => optional_string_to_py_obj(vm, &alias.alias)
}))
}
@@ -280,12 +280,8 @@ fn handler_to_ast(vm: &VirtualMachine, handler: &ast::ExceptHandler) -> PyResult
}
fn make_string_list(vm: &VirtualMachine, names: &[String]) -> PyObjectRef {
vm.ctx.new_list(
names
.iter()
.map(|x| vm.ctx.new_str(x.to_string()))
.collect(),
)
vm.ctx
.new_list(names.iter().map(|x| vm.ctx.new_str(x.to_owned())).collect())
}
fn optional_expressions_to_ast(
@@ -344,7 +340,7 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
ast::UnaryOperator::Pos => "UAdd",
};
node!(vm, UnaryOp, {
op => vm.ctx.new_str(op.to_string()),
op => vm.ctx.new_str(op.to_owned()),
operand => expression_to_ast(vm, a)?,
})
}
@@ -355,7 +351,7 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
ast::BooleanOperator::And => "And",
ast::BooleanOperator::Or => "Or",
};
let py_op = vm.ctx.new_str(str_op.to_string());
let py_op = vm.ctx.new_str(str_op.to_owned());
node!(vm, BoolOp, {
op => py_op,
@@ -380,7 +376,7 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
};
let ops = vm.ctx.new_list(
ops.iter()
.map(|x| vm.ctx.new_str(to_operator(x).to_string()))
.map(|x| vm.ctx.new_str(to_operator(x).to_owned()))
.collect(),
);
@@ -510,7 +506,7 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
}),
Attribute { value, name } => node!(vm, Attribute, {
value => expression_to_ast(vm, value)?,
attr => vm.ctx.new_str(name.to_string()),
attr => vm.ctx.new_str(name.to_owned()),
ctx => vm.ctx.none()
}),
Starred { value } => node!(vm, Starred, {
@@ -545,7 +541,7 @@ fn operator_string(op: &ast::Operator) -> String {
BitAnd => "BitAnd",
FloorDiv => "FloorDiv",
}
.to_string()
.to_owned()
}
fn parameters_to_ast(vm: &VirtualMachine, args: &ast::Parameters) -> PyResult<AstNodeRef> {
@@ -576,7 +572,7 @@ fn parameter_to_ast(vm: &VirtualMachine, parameter: &ast::Parameter) -> PyResult
};
let py_node = node!(vm, arg, {
arg => vm.ctx.new_str(parameter.arg.to_string()),
arg => vm.ctx.new_str(parameter.arg.to_owned()),
annotation => py_annotation
});
@@ -588,7 +584,7 @@ fn parameter_to_ast(vm: &VirtualMachine, parameter: &ast::Parameter) -> PyResult
fn optional_string_to_py_obj(vm: &VirtualMachine, name: &Option<String>) -> PyObjectRef {
if let Some(name) = name {
vm.ctx.new_str(name.to_string())
vm.ctx.new_str(name.to_owned())
} else {
vm.ctx.none()
}

View File

@@ -25,7 +25,7 @@ impl TryFromObject for SerializedData {
Ok(SerializedData::Ascii(a))
} else {
Err(vm.new_value_error(
"string argument should contain only ASCII characters".to_string(),
"string argument should contain only ASCII characters".to_owned(),
))
}
}
@@ -56,7 +56,7 @@ fn hex_nibble(n: u8) -> u8 {
}
}
fn binascii_hexlify(data: PyBytesLike, _vm: &VirtualMachine) -> Vec<u8> {
fn binascii_hexlify(data: PyBytesLike) -> Vec<u8> {
data.with_ref(|bytes| {
let mut hex = Vec::<u8>::with_capacity(bytes.len() * 2);
for b in bytes.iter() {
@@ -79,7 +79,7 @@ fn unhex_nibble(c: u8) -> Option<u8> {
fn binascii_unhexlify(data: SerializedData, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
data.with_ref(|hex_bytes| {
if hex_bytes.len() % 2 != 0 {
return Err(vm.new_value_error("Odd-length string".to_string()));
return Err(vm.new_value_error("Odd-length string".to_owned()));
}
let mut unhex = Vec::<u8>::with_capacity(hex_bytes.len() / 2);
@@ -87,7 +87,7 @@ fn binascii_unhexlify(data: SerializedData, vm: &VirtualMachine) -> PyResult<Vec
if let (Some(n1), Some(n2)) = (unhex_nibble(*n1), unhex_nibble(*n2)) {
unhex.push(n1 << 4 | n2);
} else {
return Err(vm.new_value_error("Non-hexadecimal digit found".to_string()));
return Err(vm.new_value_error("Non-hexadecimal digit found".to_owned()));
}
}
@@ -124,11 +124,7 @@ fn binascii_a2b_base64(s: SerializedData, vm: &VirtualMachine) -> PyResult<Vec<u
.map_err(|err| vm.new_value_error(format!("error decoding base64: {}", err)))
}
fn binascii_b2a_base64(
data: PyBytesLike,
NewlineArg { newline }: NewlineArg,
_vm: &VirtualMachine,
) -> Vec<u8> {
fn binascii_b2a_base64(data: PyBytesLike, NewlineArg { newline }: NewlineArg) -> Vec<u8> {
let mut encoded = data.with_ref(base64::encode).into_bytes();
if newline {
encoded.push(b'\n');

View File

@@ -57,7 +57,7 @@ impl PyDeque {
}
#[pymethod]
fn append(&self, obj: PyObjectRef, _vm: &VirtualMachine) {
fn append(&self, obj: PyObjectRef) {
let mut deque = self.deque.borrow_mut();
if self.maxlen.get() == Some(deque.len()) {
deque.pop_front();
@@ -66,7 +66,7 @@ impl PyDeque {
}
#[pymethod]
fn appendleft(&self, obj: PyObjectRef, _vm: &VirtualMachine) {
fn appendleft(&self, obj: PyObjectRef) {
let mut deque = self.deque.borrow_mut();
if self.maxlen.get() == Some(deque.len()) {
deque.pop_back();
@@ -75,12 +75,12 @@ impl PyDeque {
}
#[pymethod]
fn clear(&self, _vm: &VirtualMachine) {
fn clear(&self) {
self.deque.borrow_mut().clear()
}
#[pymethod]
fn copy(&self, _vm: &VirtualMachine) -> Self {
fn copy(&self) -> Self {
self.clone()
}
@@ -99,7 +99,7 @@ impl PyDeque {
fn extend(&self, iter: PyIterable, vm: &VirtualMachine) -> PyResult<()> {
// TODO: use length_hint here and for extendleft
for elem in iter.iter(vm)? {
self.append(elem?, vm);
self.append(elem?);
}
Ok(())
}
@@ -107,7 +107,7 @@ impl PyDeque {
#[pymethod]
fn extendleft(&self, iter: PyIterable, vm: &VirtualMachine) -> PyResult<()> {
for elem in iter.iter(vm)? {
self.appendleft(elem?, vm);
self.appendleft(elem?);
}
Ok(())
}
@@ -140,7 +140,7 @@ impl PyDeque {
let mut deque = self.deque.borrow_mut();
if self.maxlen.get() == Some(deque.len()) {
return Err(vm.new_index_error("deque already at its maximum size".to_string()));
return Err(vm.new_index_error("deque already at its maximum size".to_owned()));
}
let idx = if idx < 0 {
@@ -165,7 +165,7 @@ impl PyDeque {
self.deque
.borrow_mut()
.pop_back()
.ok_or_else(|| vm.new_index_error("pop from an empty deque".to_string()))
.ok_or_else(|| vm.new_index_error("pop from an empty deque".to_owned()))
}
#[pymethod]
@@ -173,7 +173,7 @@ impl PyDeque {
self.deque
.borrow_mut()
.pop_front()
.ok_or_else(|| vm.new_index_error("pop from an empty deque".to_string()))
.ok_or_else(|| vm.new_index_error("pop from an empty deque".to_owned()))
}
#[pymethod]
@@ -187,17 +187,17 @@ impl PyDeque {
}
}
idx.map(|idx| deque.remove(idx).unwrap())
.ok_or_else(|| vm.new_value_error("deque.remove(x): x not in deque".to_string()))
.ok_or_else(|| vm.new_value_error("deque.remove(x): x not in deque".to_owned()))
}
#[pymethod]
fn reverse(&self, _vm: &VirtualMachine) {
fn reverse(&self) {
self.deque
.replace_with(|deque| deque.iter().cloned().rev().collect());
}
#[pymethod]
fn rotate(&self, mid: OptionalArg<isize>, _vm: &VirtualMachine) {
fn rotate(&self, mid: OptionalArg<isize>) {
let mut deque = self.deque.borrow_mut();
let mid = mid.unwrap_or(1);
if mid < 0 {
@@ -208,12 +208,12 @@ impl PyDeque {
}
#[pyproperty]
fn maxlen(&self, _vm: &VirtualMachine) -> Option<usize> {
fn maxlen(&self) -> Option<usize> {
self.maxlen.get()
}
#[pyproperty(setter)]
fn set_maxlen(&self, maxlen: Option<usize>, _vm: &VirtualMachine) {
fn set_maxlen(&self, maxlen: Option<usize>) {
self.maxlen.set(maxlen);
}
@@ -233,7 +233,7 @@ impl PyDeque {
.unwrap_or_default();
format!("deque([{}]{})", elements.into_iter().format(", "), maxlen)
} else {
"[...]".to_string()
"[...]".to_owned()
};
Ok(repr)
}
@@ -326,7 +326,7 @@ impl PyDeque {
}
#[pymethod(name = "__mul__")]
fn mul(&self, n: isize, _vm: &VirtualMachine) -> Self {
fn mul(&self, n: isize) -> Self {
let deque: &VecDeque<_> = &self.deque.borrow();
let mul = sequence::seq_mul(deque, n);
let skipped = if let Some(maxlen) = self.maxlen.get() {
@@ -342,12 +342,12 @@ impl PyDeque {
}
#[pymethod(name = "__len__")]
fn len(&self, _vm: &VirtualMachine) -> usize {
fn len(&self) -> usize {
self.deque.borrow().len()
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyDequeIterator {
fn iter(zelf: PyRef<Self>) -> PyDequeIterator {
PyDequeIterator {
position: Cell::new(0),
deque: zelf,
@@ -382,7 +382,7 @@ impl PyDequeIterator {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -35,7 +35,7 @@ impl ReaderOption {
1 => bytes[0],
_ => {
let msg = r#""delimiter" must be a 1-character string"#;
return Err(vm.new_type_error(msg.to_string()));
return Err(vm.new_type_error(msg.to_owned()));
}
}
} else {
@@ -48,7 +48,7 @@ impl ReaderOption {
1 => bytes[0],
_ => {
let msg = r#""quotechar" must be a 1-character string"#;
return Err(vm.new_type_error(msg.to_string()));
return Err(vm.new_type_error(msg.to_owned()));
}
}
} else {
@@ -190,7 +190,7 @@ fn csv_reader(fp: PyObjectRef, args: PyFuncArgs, vm: &VirtualMachine) -> PyResul
if let Ok(iterable) = PyIterable::<PyObjectRef>::try_from_object(vm, fp) {
build_reader(iterable, args, vm)
} else {
Err(vm.new_type_error("argument 1 must be an iterator".to_string()))
Err(vm.new_type_error("argument 1 must be an iterator".to_owned()))
}
}

View File

@@ -23,7 +23,7 @@ fn dis_compiler_flag_names(vm: &VirtualMachine) -> PyObjectRef {
for (name, flag) in CodeFlags::NAME_MAPPING {
dict.set_item(
&vm.ctx.new_int(flag.bits()),
vm.ctx.new_str((*name).to_string()),
vm.ctx.new_str((*name).to_owned()),
vm,
)
.unwrap();

View File

@@ -20,7 +20,7 @@ fn dump_traceback(_file: OptionalArg<i64>, _all_threads: OptionalArg<bool>, vm:
}
}
fn enable(_file: OptionalArg<i64>, _all_threads: OptionalArg<bool>, _vm: &VirtualMachine) {
fn enable(_file: OptionalArg<i64>, _all_threads: OptionalArg<bool>) {
// TODO
}
@@ -29,7 +29,6 @@ fn register(
_file: OptionalArg<i64>,
_all_threads: OptionalArg<bool>,
_chain: OptionalArg<bool>,
_vm: &VirtualMachine,
) {
// TODO
}

View File

@@ -28,7 +28,7 @@ fn functools_reduce(
let exc_type = vm.ctx.exceptions.type_error.clone();
vm.new_exception_msg(
exc_type,
"reduce() of empty sequence with no initial value".to_string(),
"reduce() of empty sequence with no initial value".to_owned(),
)
} else {
err

View File

@@ -36,7 +36,7 @@ impl PyValue for PyHasher {
impl PyHasher {
fn new(name: &str, d: HashWrapper) -> Self {
PyHasher {
name: name.to_string(),
name: name.to_owned(),
buffer: RefCell::new(d),
}
}
@@ -49,7 +49,7 @@ impl PyHasher {
}
#[pyproperty(name = "name")]
fn name(&self, _vm: &VirtualMachine) -> String {
fn name(&self) -> String {
self.name.clone()
}
@@ -65,13 +65,13 @@ impl PyHasher {
}
#[pymethod(name = "digest")]
fn digest(&self, _vm: &VirtualMachine) -> PyBytes {
fn digest(&self) -> PyBytes {
let result = self.get_digest();
PyBytes::new(result)
}
#[pymethod(name = "hexdigest")]
fn hexdigest(&self, _vm: &VirtualMachine) -> String {
fn hexdigest(&self) -> String {
let result = self.get_digest();
hex::encode(result)
}
@@ -158,11 +158,11 @@ fn sha3_512(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHa
}
fn shake128(_data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
Err(vm.new_not_implemented_error("shake256".to_string()))
Err(vm.new_not_implemented_error("shake256".to_owned()))
}
fn shake256(_data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {
Err(vm.new_not_implemented_error("shake256".to_string()))
Err(vm.new_not_implemented_error("shake256".to_owned()))
}
fn blake2b(data: OptionalArg<PyBytesRef>, vm: &VirtualMachine) -> PyResult<PyHasher> {

View File

@@ -47,7 +47,7 @@ fn imp_create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
}
}
fn imp_exec_builtin(_mod: PyModuleRef, _vm: &VirtualMachine) -> i32 {
fn imp_exec_builtin(_mod: PyModuleRef) -> i32 {
// TOOD: Should we do something here?
0
}
@@ -80,7 +80,7 @@ fn imp_is_frozen_package(name: PyStringRef, vm: &VirtualMachine) -> PyResult<boo
})
}
fn imp_fix_co_filename(_code: PyObjectRef, _path: PyStringRef, _vm: &VirtualMachine) {
fn imp_fix_co_filename(_code: PyObjectRef, _path: PyStringRef) {
// TODO:
}

View File

@@ -119,7 +119,7 @@ impl PyStringIORef {
if buffer.is_some() {
Ok(RefMut::map(buffer, |opt| opt.as_mut().unwrap()))
} else {
Err(vm.new_value_error("I/O operation on closed file.".to_string()))
Err(vm.new_value_error("I/O operation on closed file.".to_owned()))
}
}
@@ -129,7 +129,7 @@ impl PyStringIORef {
match self.buffer(vm)?.write(bytes) {
Some(value) => Ok(vm.ctx.new_int(value)),
None => Err(vm.new_type_error("Error Writing String".to_string())),
None => Err(vm.new_type_error("Error Writing String".to_owned())),
}
}
@@ -137,7 +137,7 @@ impl PyStringIORef {
fn getvalue(self, vm: &VirtualMachine) -> PyResult {
match String::from_utf8(self.buffer(vm)?.getvalue()) {
Ok(result) => Ok(vm.ctx.new_str(result)),
Err(_) => Err(vm.new_value_error("Error Retrieving Value".to_string())),
Err(_) => Err(vm.new_value_error("Error Retrieving Value".to_owned())),
}
}
@@ -145,11 +145,11 @@ impl PyStringIORef {
fn seek(self, offset: u64, vm: &VirtualMachine) -> PyResult {
match self.buffer(vm)?.seek(offset) {
Some(value) => Ok(vm.ctx.new_int(value)),
None => Err(vm.new_value_error("Error Performing Operation".to_string())),
None => Err(vm.new_value_error("Error Performing Operation".to_owned())),
}
}
fn seekable(self, _vm: &VirtualMachine) -> bool {
fn seekable(self) -> bool {
true
}
@@ -164,7 +164,7 @@ impl PyStringIORef {
match String::from_utf8(data) {
Ok(value) => Ok(vm.ctx.new_str(value)),
Err(_) => Err(vm.new_value_error("Error Retrieving Value".to_string())),
Err(_) => Err(vm.new_value_error("Error Retrieving Value".to_owned())),
}
}
@@ -175,7 +175,7 @@ impl PyStringIORef {
fn readline(self, vm: &VirtualMachine) -> PyResult<String> {
match self.buffer(vm)?.readline() {
Some(line) => Ok(line),
None => Err(vm.new_value_error("Error Performing Operation".to_string())),
None => Err(vm.new_value_error("Error Performing Operation".to_owned())),
}
}
@@ -186,11 +186,11 @@ impl PyStringIORef {
Ok(())
}
fn closed(self, _vm: &VirtualMachine) -> bool {
fn closed(self) -> bool {
self.buffer.borrow().is_none()
}
fn close(self, _vm: &VirtualMachine) {
fn close(self) {
self.buffer.replace(None);
}
}
@@ -237,7 +237,7 @@ impl PyBytesIORef {
if buffer.is_some() {
Ok(RefMut::map(buffer, |opt| opt.as_mut().unwrap()))
} else {
Err(vm.new_value_error("I/O operation on closed file.".to_string()))
Err(vm.new_value_error("I/O operation on closed file.".to_owned()))
}
}
@@ -245,7 +245,7 @@ impl PyBytesIORef {
let mut buffer = self.buffer(vm)?;
match data.with_ref(|b| buffer.write(b)) {
Some(value) => Ok(value),
None => Err(vm.new_type_error("Error Writing Bytes".to_string())),
None => Err(vm.new_type_error("Error Writing Bytes".to_owned())),
}
}
//Retrieves the entire bytes object value from the underlying buffer
@@ -259,7 +259,7 @@ impl PyBytesIORef {
fn read(self, bytes: OptionalOption<i64>, vm: &VirtualMachine) -> PyResult {
match self.buffer(vm)?.read(byte_count(bytes)) {
Some(value) => Ok(vm.ctx.new_bytes(value)),
None => Err(vm.new_value_error("Error Retrieving Value".to_string())),
None => Err(vm.new_value_error("Error Retrieving Value".to_owned())),
}
}
@@ -267,11 +267,11 @@ impl PyBytesIORef {
fn seek(self, offset: u64, vm: &VirtualMachine) -> PyResult {
match self.buffer(vm)?.seek(offset) {
Some(value) => Ok(vm.ctx.new_int(value)),
None => Err(vm.new_value_error("Error Performing Operation".to_string())),
None => Err(vm.new_value_error("Error Performing Operation".to_owned())),
}
}
fn seekable(self, _vm: &VirtualMachine) -> bool {
fn seekable(self) -> bool {
true
}
@@ -282,7 +282,7 @@ impl PyBytesIORef {
fn readline(self, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
match self.buffer(vm)?.readline() {
Some(line) => Ok(line.as_bytes().to_vec()),
None => Err(vm.new_value_error("Error Performing Operation".to_string())),
None => Err(vm.new_value_error("Error Performing Operation".to_owned())),
}
}
@@ -293,11 +293,11 @@ impl PyBytesIORef {
Ok(())
}
fn closed(self, _vm: &VirtualMachine) -> bool {
fn closed(self) -> bool {
self.buffer.borrow().is_none()
}
fn close(self, _vm: &VirtualMachine) {
fn close(self) {
self.buffer.replace(None);
}
}
@@ -318,7 +318,7 @@ fn bytes_io_new(
.into_ref_with_type(vm, cls)
}
fn io_base_cm_enter(instance: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef {
fn io_base_cm_enter(instance: PyObjectRef) -> PyObjectRef {
instance.clone()
}
@@ -328,15 +328,15 @@ fn io_base_cm_exit(instance: PyObjectRef, _args: PyFuncArgs, vm: &VirtualMachine
}
// TODO Check if closed, then if so raise ValueError
fn io_base_flush(_self: PyObjectRef, _vm: &VirtualMachine) {}
fn io_base_flush(_self: PyObjectRef) {}
fn io_base_seekable(_self: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn io_base_seekable(_self: PyObjectRef) -> bool {
false
}
fn io_base_readable(_self: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn io_base_readable(_self: PyObjectRef) -> bool {
false
}
fn io_base_writable(_self: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn io_base_writable(_self: PyObjectRef) -> bool {
false
}
@@ -383,7 +383,7 @@ fn io_base_checkclosed(
if objbool::boolval(vm, vm.get_attribute(instance, "closed")?)? {
let msg = msg
.flat_option()
.unwrap_or_else(|| vm.new_str("I/O operation on closed file.".to_string()));
.unwrap_or_else(|| vm.new_str("I/O operation on closed file.".to_owned()));
Err(vm.new_exception(vm.ctx.exceptions.value_error.clone(), vec![msg]))
} else {
Ok(())
@@ -398,7 +398,7 @@ fn io_base_checkreadable(
if !objbool::boolval(vm, vm.call_method(&instance, "readable", vec![])?)? {
let msg = msg
.flat_option()
.unwrap_or_else(|| vm.new_str("File or stream is not readable.".to_string()));
.unwrap_or_else(|| vm.new_str("File or stream is not readable.".to_owned()));
Err(vm.new_exception(vm.ctx.exceptions.value_error.clone(), vec![msg]))
} else {
Ok(())
@@ -413,7 +413,7 @@ fn io_base_checkwritable(
if !objbool::boolval(vm, vm.call_method(&instance, "writable", vec![])?)? {
let msg = msg
.flat_option()
.unwrap_or_else(|| vm.new_str("File or stream is not writable.".to_string()));
.unwrap_or_else(|| vm.new_str("File or stream is not writable.".to_owned()));
Err(vm.new_exception(vm.ctx.exceptions.value_error.clone(), vec![msg]))
} else {
Ok(())
@@ -428,14 +428,14 @@ fn io_base_checkseekable(
if !objbool::boolval(vm, vm.call_method(&instance, "seekable", vec![])?)? {
let msg = msg
.flat_option()
.unwrap_or_else(|| vm.new_str("File or stream is not seekable.".to_string()));
.unwrap_or_else(|| vm.new_str("File or stream is not seekable.".to_owned()));
Err(vm.new_exception(vm.ctx.exceptions.value_error.clone(), vec![msg]))
} else {
Ok(())
}
}
fn io_base_iter(instance: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef {
fn io_base_iter(instance: PyObjectRef) -> PyObjectRef {
instance
}
fn io_base_next(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
@@ -505,7 +505,7 @@ fn buffered_reader_read(
)
}
fn buffered_reader_seekable(_self: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn buffered_reader_seekable(_self: PyObjectRef) -> bool {
true
}
@@ -564,7 +564,7 @@ mod fileio {
vm.set_attr(&file_io, "name", name)?;
vm.set_attr(&file_io, "__fileno", vm.new_int(file_no))?;
vm.set_attr(&file_io, "closefd", vm.new_bool(false))?;
vm.set_attr(&file_io, "closed", vm.new_bool(false))?;
vm.set_attr(&file_io, "__closed", vm.new_bool(false))?;
Ok(vm.get_none())
}
@@ -614,7 +614,7 @@ mod fileio {
) -> PyResult<()> {
if !obj.readonly() {
return Err(vm.new_type_error(
"readinto() argument must be read-write bytes-like object".to_string(),
"readinto() argument must be read-write bytes-like object".to_owned(),
));
}
@@ -632,7 +632,7 @@ mod fileio {
value_mut.clear();
match f.read_to_end(value_mut) {
Ok(_) => {}
Err(_) => return Err(vm.new_value_error("Error reading from Take".to_string())),
Err(_) => return Err(vm.new_value_error("Error reading from Take".to_owned())),
}
};
@@ -665,7 +665,7 @@ mod fileio {
winapi::um::handleapi::CloseHandle(raw_handle as _);
}
vm.set_attr(&instance, "closefd", vm.new_bool(true))?;
vm.set_attr(&instance, "closed", vm.new_bool(true))?;
vm.set_attr(&instance, "__closed", vm.new_bool(true))?;
Ok(())
}
@@ -676,11 +676,11 @@ mod fileio {
libc::close(raw_fd as _);
}
vm.set_attr(&instance, "closefd", vm.new_bool(true))?;
vm.set_attr(&instance, "closed", vm.new_bool(true))?;
vm.set_attr(&instance, "__closed", vm.new_bool(true))?;
Ok(())
}
fn file_io_seekable(_self: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn file_io_seekable(_self: PyObjectRef) -> bool {
true
}
@@ -709,7 +709,7 @@ fn buffered_writer_write(instance: PyObjectRef, obj: PyObjectRef, vm: &VirtualMa
vm.call_method(&raw, "write", vec![obj.clone()])
}
fn buffered_writer_seekable(_self: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn buffered_writer_seekable(_self: PyObjectRef) -> bool {
true
}
@@ -722,7 +722,7 @@ fn text_io_wrapper_init(
Ok(())
}
fn text_io_wrapper_seekable(_self: PyObjectRef, _vm: &VirtualMachine) -> bool {
fn text_io_wrapper_seekable(_self: PyObjectRef) -> bool {
true
}
@@ -736,7 +736,7 @@ fn text_io_wrapper_read(
if !objtype::isinstance(&raw, &buffered_reader_class) {
// TODO: this should be io.UnsupportedOperation error which derives both from ValueError *and* OSError
return Err(vm.new_value_error("not readable".to_string()));
return Err(vm.new_value_error("not readable".to_owned()));
}
let bytes = vm.call_method(
@@ -767,15 +767,15 @@ fn text_io_wrapper_write(
if !objtype::isinstance(&raw, &buffered_writer_class) {
// TODO: this should be io.UnsupportedOperation error which derives from ValueError and OSError
return Err(vm.new_value_error("not writable".to_string()));
return Err(vm.new_value_error("not writable".to_owned()));
}
let bytes = obj.as_str().to_string().into_bytes();
let bytes = obj.as_str().to_owned().into_bytes();
let len = vm.call_method(&raw, "write", vec![vm.ctx.new_bytes(bytes.clone())])?;
let len = objint::get_value(&len).to_usize().ok_or_else(|| {
vm.new_overflow_error("int to large to convert to Rust usize".to_string())
})?;
let len = objint::get_value(&len)
.to_usize()
.ok_or_else(|| vm.new_overflow_error("int to large to convert to Rust usize".to_owned()))?;
// returns the count of unicode code points written
let len = from_utf8(&bytes[..len])
@@ -795,7 +795,7 @@ fn text_io_wrapper_readline(
if !objtype::isinstance(&raw, &buffered_reader_class) {
// TODO: this should be io.UnsupportedOperation error which derives both from ValueError *and* OSError
return Err(vm.new_value_error("not readable".to_string()));
return Err(vm.new_value_error("not readable".to_owned()));
}
let bytes = vm.call_method(
@@ -833,7 +833,7 @@ fn split_mode_string(mode_string: &str) -> Result<(String, String), String> {
// no duplicates allowed
return Err(format!("invalid mode: '{}'", mode_string));
} else {
return Err("can't have text and binary mode at once".to_string());
return Err("can't have text and binary mode at once".to_owned());
}
}
typ = ch;
@@ -845,7 +845,7 @@ fn split_mode_string(mode_string: &str) -> Result<(String, String), String> {
return Err(format!("invalid mode: '{}'", mode_string));
} else {
return Err(
"must have exactly one of create/read/write/append mode".to_string()
"must have exactly one of create/read/write/append mode".to_owned()
);
}
}
@@ -858,7 +858,7 @@ fn split_mode_string(mode_string: &str) -> Result<(String, String), String> {
if mode == '\0' {
return Err(
"Must have exactly one of create/read/write/append mode and at most one plus"
.to_string(),
.to_owned(),
);
}
let mut mode = mode.to_string();
@@ -896,7 +896,7 @@ pub fn io_open(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
let file_io_class = vm.get_attribute(io_module.clone(), "FileIO").map_err(|_| {
// TODO: UnsupportedOperation here
vm.new_os_error(
"Couldn't get FileIO, io.open likely isn't supported on your platform".to_string(),
"Couldn't get FileIO, io.open likely isn't supported on your platform".to_owned(),
)
})?;
let file_io_obj = vm.invoke(
@@ -952,7 +952,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
"readable" => ctx.new_method(io_base_readable),
"writable" => ctx.new_method(io_base_writable),
"flush" => ctx.new_method(io_base_flush),
"closed" => ctx.new_property(io_base_closed),
"closed" => ctx.new_readonly_getset("closed", io_base_closed),
"__closed" => ctx.new_bool(false),
"close" => ctx.new_method(io_base_close),
"readline" => ctx.new_method(io_base_readline),
@@ -1017,7 +1017,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
"tell" => ctx.new_method(PyStringIORef::tell),
"readline" => ctx.new_method(PyStringIORef::readline),
"truncate" => ctx.new_method(PyStringIORef::truncate),
"closed" => ctx.new_property(PyStringIORef::closed),
"closed" => ctx.new_readonly_getset("closed", PyStringIORef::closed),
"close" => ctx.new_method(PyStringIORef::close),
});
@@ -1033,7 +1033,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
"tell" => ctx.new_method(PyBytesIORef::tell),
"readline" => ctx.new_method(PyBytesIORef::readline),
"truncate" => ctx.new_method(PyBytesIORef::truncate),
"closed" => ctx.new_property(PyBytesIORef::closed),
"closed" => ctx.new_readonly_getset("closed", PyBytesIORef::closed),
"close" => ctx.new_method(PyBytesIORef::close),
});
@@ -1084,15 +1084,15 @@ mod tests {
fn test_invalid_mode() {
assert_eq!(
split_mode_string("rbsss"),
Err("invalid mode: 'rbsss'".to_string())
Err("invalid mode: 'rbsss'".to_owned())
);
assert_eq!(
split_mode_string("rrb"),
Err("invalid mode: 'rrb'".to_string())
Err("invalid mode: 'rrb'".to_owned())
);
assert_eq!(
split_mode_string("rbb"),
Err("invalid mode: 'rbb'".to_string())
Err("invalid mode: 'rbb'".to_owned())
);
}
@@ -1102,21 +1102,21 @@ mod tests {
split_mode_string(""),
Err(
"Must have exactly one of create/read/write/append mode and at most one plus"
.to_string()
.to_owned()
)
);
assert_eq!(
split_mode_string("b"),
Err(
"Must have exactly one of create/read/write/append mode and at most one plus"
.to_string()
.to_owned()
)
);
assert_eq!(
split_mode_string("t"),
Err(
"Must have exactly one of create/read/write/append mode and at most one plus"
.to_string()
.to_owned()
)
);
}
@@ -1125,7 +1125,7 @@ mod tests {
fn test_text_and_binary_at_once() {
assert_eq!(
split_mode_string("rbt"),
Err("can't have text and binary mode at once".to_string())
Err("can't have text and binary mode at once".to_owned())
);
}
@@ -1133,7 +1133,7 @@ mod tests {
fn test_exactly_one_mode() {
assert_eq!(
split_mode_string("rwb"),
Err("must have exactly one of create/read/write/append mode".to_string())
Err("must have exactly one of create/read/write/append mode".to_owned())
);
}
@@ -1141,7 +1141,7 @@ mod tests {
fn test_at_most_one_plus() {
assert_eq!(
split_mode_string("a++"),
Err("invalid mode: 'a++'".to_string())
Err("invalid mode: 'a++'".to_owned())
);
}

View File

@@ -67,7 +67,7 @@ impl PyItertoolsChain {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
@@ -134,7 +134,7 @@ impl PyItertoolsCompress {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -178,14 +178,14 @@ impl PyItertoolsCount {
}
#[pymethod(name = "__next__")]
fn next(&self, _vm: &VirtualMachine) -> PyResult<PyInt> {
fn next(&self) -> PyResult<PyInt> {
let result = self.cur.borrow().clone();
*self.cur.borrow_mut() += &self.step;
Ok(PyInt::new(result))
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -252,7 +252,7 @@ impl PyItertoolsCycle {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -304,7 +304,7 @@ impl PyItertoolsRepeat {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
@@ -353,7 +353,7 @@ impl PyItertoolsStarmap {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -412,7 +412,7 @@ impl PyItertoolsTakewhile {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -470,7 +470,7 @@ impl PyItertoolsDropwhile {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -528,7 +528,7 @@ impl PyItertoolsIslice {
let start = if !start.is(&vm.get_none()) {
pyobject_to_opt_usize(start, &vm).ok_or_else(|| {
vm.new_value_error(
"Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize.".to_string(),
"Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize.".to_owned(),
)
})?
} else {
@@ -538,7 +538,7 @@ impl PyItertoolsIslice {
let step = if !step.is(&vm.get_none()) {
pyobject_to_opt_usize(step, &vm).ok_or_else(|| {
vm.new_value_error(
"Step for islice() must be a positive integer or None.".to_string(),
"Step for islice() must be a positive integer or None.".to_owned(),
)
})?
} else {
@@ -553,7 +553,7 @@ impl PyItertoolsIslice {
Some(pyobject_to_opt_usize(stop, &vm).ok_or_else(|| {
vm.new_value_error(
"Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize."
.to_string(),
.to_owned(),
)
})?)
} else {
@@ -596,7 +596,7 @@ impl PyItertoolsIslice {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -652,7 +652,7 @@ impl PyItertoolsFilterFalse {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -711,7 +711,7 @@ impl PyItertoolsAccumulate {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -810,7 +810,7 @@ impl PyItertoolsTee {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -927,7 +927,7 @@ impl PyItertoolsProduct {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}
@@ -961,7 +961,7 @@ impl PyItertoolsCombinations {
let r = r.as_bigint();
if r.is_negative() {
return Err(vm.new_value_error("r must be non-negative".to_string()));
return Err(vm.new_value_error("r must be non-negative".to_owned()));
}
let r = r.to_usize().unwrap();
@@ -977,7 +977,7 @@ impl PyItertoolsCombinations {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
@@ -1060,7 +1060,7 @@ impl PyItertoolsCombinationsWithReplacement {
let r = r.as_bigint();
if r.is_negative() {
return Err(vm.new_value_error("r must be non-negative".to_string()));
return Err(vm.new_value_error("r must be non-negative".to_owned()));
}
let r = r.to_usize().unwrap();
@@ -1076,7 +1076,7 @@ impl PyItertoolsCombinationsWithReplacement {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
@@ -1161,11 +1161,11 @@ impl PyItertoolsPermutations {
Some(r) => {
let val = r
.payload::<PyInt>()
.ok_or_else(|| vm.new_type_error("Expected int as r".to_string()))?
.ok_or_else(|| vm.new_type_error("Expected int as r".to_owned()))?
.as_bigint();
if val.is_negative() {
return Err(vm.new_value_error("r must be non-negative".to_string()));
return Err(vm.new_value_error("r must be non-negative".to_owned()));
}
val.to_usize().unwrap()
}
@@ -1184,7 +1184,7 @@ impl PyItertoolsPermutations {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
@@ -1333,7 +1333,7 @@ impl PyItertoolsZiplongest {
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
}

View File

@@ -21,7 +21,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
let keyword_kwlist = ctx.new_list(
lexer::get_keywords()
.keys()
.map(|k| ctx.new_str(k.to_string()))
.map(|k| ctx.new_str(k.to_owned()))
.collect(),
);

View File

@@ -4,7 +4,7 @@ use crate::obj::objcode::{PyCode, PyCodeRef};
use crate::pyobject::{PyObjectRef, PyResult};
use crate::vm::VirtualMachine;
fn marshal_dumps(co: PyCodeRef, _vm: &VirtualMachine) -> PyBytes {
fn marshal_dumps(co: PyCodeRef) -> PyBytes {
PyBytes::new(co.code.to_bytes())
}

View File

@@ -25,7 +25,7 @@ use std::cmp::Ordering;
// Helper macro:
macro_rules! make_math_func {
( $fname:ident, $fun:ident ) => {
fn $fname(value: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn $fname(value: IntoPyFloat) -> f64 {
value.to_f64().$fun()
}
};
@@ -33,7 +33,7 @@ macro_rules! make_math_func {
macro_rules! make_math_func_bool {
( $fname:ident, $fun:ident ) => {
fn $fname(value: IntoPyFloat, _vm: &VirtualMachine) -> bool {
fn $fname(value: IntoPyFloat) -> bool {
value.to_f64().$fun()
}
};
@@ -72,7 +72,7 @@ fn math_isclose(args: IsCloseArgs, vm: &VirtualMachine) -> PyResult<bool> {
};
if rel_tol < 0.0 || abs_tol < 0.0 {
return Err(vm.new_value_error("tolerances must be non-negative".to_string()));
return Err(vm.new_value_error("tolerances must be non-negative".to_owned()));
}
if a == b {
@@ -98,7 +98,7 @@ fn math_isclose(args: IsCloseArgs, vm: &VirtualMachine) -> PyResult<bool> {
Ok((diff <= (rel_tol * b).abs()) || (diff <= (rel_tol * a).abs()) || (diff <= abs_tol))
}
fn math_copysign(a: IntoPyFloat, b: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_copysign(a: IntoPyFloat, b: IntoPyFloat) -> f64 {
let a = a.to_f64();
let b = b.to_f64();
if a.is_nan() || b.is_nan() {
@@ -112,18 +112,18 @@ fn math_copysign(a: IntoPyFloat, b: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
make_math_func!(math_exp, exp);
make_math_func!(math_expm1, exp_m1);
fn math_log(x: IntoPyFloat, base: OptionalArg<IntoPyFloat>, _vm: &VirtualMachine) -> f64 {
fn math_log(x: IntoPyFloat, base: OptionalArg<IntoPyFloat>) -> f64 {
base.map_or_else(|| x.to_f64().ln(), |base| x.to_f64().log(base.to_f64()))
}
fn math_log1p(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_log1p(x: IntoPyFloat) -> f64 {
(x.to_f64() + 1.0).ln()
}
make_math_func!(math_log2, log2);
make_math_func!(math_log10, log10);
fn math_pow(x: IntoPyFloat, y: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_pow(x: IntoPyFloat, y: IntoPyFloat) -> f64 {
x.to_f64().powf(y.to_f64())
}
@@ -134,24 +134,24 @@ make_math_func!(math_acos, acos);
make_math_func!(math_asin, asin);
make_math_func!(math_atan, atan);
fn math_atan2(y: IntoPyFloat, x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_atan2(y: IntoPyFloat, x: IntoPyFloat) -> f64 {
y.to_f64().atan2(x.to_f64())
}
make_math_func!(math_cos, cos);
fn math_hypot(x: IntoPyFloat, y: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_hypot(x: IntoPyFloat, y: IntoPyFloat) -> f64 {
x.to_f64().hypot(y.to_f64())
}
make_math_func!(math_sin, sin);
make_math_func!(math_tan, tan);
fn math_degrees(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_degrees(x: IntoPyFloat) -> f64 {
x.to_f64() * (180.0 / std::f64::consts::PI)
}
fn math_radians(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_radians(x: IntoPyFloat) -> f64 {
x.to_f64() * (std::f64::consts::PI / 180.0)
}
@@ -164,7 +164,7 @@ make_math_func!(math_sinh, sinh);
make_math_func!(math_tanh, tanh);
// Special functions:
fn math_erf(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_erf(x: IntoPyFloat) -> f64 {
let x = x.to_f64();
if x.is_nan() {
x
@@ -173,7 +173,7 @@ fn math_erf(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
}
}
fn math_erfc(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_erfc(x: IntoPyFloat) -> f64 {
let x = x.to_f64();
if x.is_nan() {
x
@@ -182,7 +182,7 @@ fn math_erfc(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
}
}
fn math_gamma(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_gamma(x: IntoPyFloat) -> f64 {
let x = x.to_f64();
if x.is_finite() {
gamma(x)
@@ -193,7 +193,7 @@ fn math_gamma(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
}
}
fn math_lgamma(x: IntoPyFloat, _vm: &VirtualMachine) -> f64 {
fn math_lgamma(x: IntoPyFloat) -> f64 {
let x = x.to_f64();
if x.is_finite() {
ln_gamma(x)
@@ -251,7 +251,7 @@ fn math_floor(value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
}
}
fn math_frexp(value: IntoPyFloat, _vm: &VirtualMachine) -> (f64, i32) {
fn math_frexp(value: IntoPyFloat) -> (f64, i32) {
let value = value.to_f64();
if value.is_finite() {
let (m, e) = objfloat::ufrexp(value);
@@ -261,11 +261,11 @@ fn math_frexp(value: IntoPyFloat, _vm: &VirtualMachine) -> (f64, i32) {
}
}
fn math_ldexp(value: PyFloatRef, i: PyIntRef, _vm: &VirtualMachine) -> f64 {
fn math_ldexp(value: PyFloatRef, i: PyIntRef) -> f64 {
value.to_f64() * (2_f64).powf(i.as_bigint().to_f64().unwrap())
}
fn math_gcd(a: PyIntRef, b: PyIntRef, _vm: &VirtualMachine) -> BigInt {
fn math_gcd(a: PyIntRef, b: PyIntRef) -> BigInt {
use num_integer::Integer;
a.as_bigint().gcd(b.as_bigint())
}
@@ -273,7 +273,7 @@ fn math_gcd(a: PyIntRef, b: PyIntRef, _vm: &VirtualMachine) -> BigInt {
fn math_factorial(value: PyIntRef, vm: &VirtualMachine) -> PyResult<BigInt> {
let value = value.as_bigint();
if *value < BigInt::zero() {
return Err(vm.new_value_error("factorial() not defined for negative values".to_string()));
return Err(vm.new_value_error("factorial() not defined for negative values".to_owned()));
} else if *value <= BigInt::one() {
return Ok(BigInt::from(1u64));
}
@@ -281,7 +281,7 @@ fn math_factorial(value: PyIntRef, vm: &VirtualMachine) -> PyResult<BigInt> {
Ok(ret)
}
fn math_modf(x: IntoPyFloat, _vm: &VirtualMachine) -> (f64, f64) {
fn math_modf(x: IntoPyFloat) -> (f64, f64) {
let x = x.to_f64();
if !x.is_finite() {
if x.is_infinite() {
@@ -306,7 +306,7 @@ fn math_nextafter(x: IntoPyFloat, y: IntoPyFloat) -> PyResult<f64> {
#[cfg(target_arch = "wasm32")]
fn math_nextafter(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
Err(vm.new_not_implemented_error("not implemented for this platform".to_string()))
Err(vm.new_not_implemented_error("not implemented for this platform".to_owned()))
}
fn fmod(x: f64, y: f64) -> f64 {
@@ -324,7 +324,7 @@ fn math_fmod(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f6
let r = fmod(x, y);
if r.is_nan() && !x.is_nan() && !y.is_nan() {
return Err(vm.new_value_error("math domain error".to_string()));
return Err(vm.new_value_error("math domain error".to_owned()));
}
Ok(r)
@@ -362,7 +362,7 @@ fn math_remainder(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResu
return Ok(std::f64::NAN);
}
if y.is_infinite() {
return Err(vm.new_value_error("math domain error".to_string()));
return Err(vm.new_value_error("math domain error".to_owned()));
}
Ok(x)
}

View File

@@ -62,65 +62,65 @@ pub type StdlibInitFunc = Box<dyn Fn(&VirtualMachine) -> PyObjectRef>;
pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
#[allow(unused_mut)]
let mut modules = hashmap! {
"array".to_string() => Box::new(array::make_module) as StdlibInitFunc,
"binascii".to_string() => Box::new(binascii::make_module),
"dis".to_string() => Box::new(dis::make_module),
"_collections".to_string() => Box::new(collections::make_module),
"_csv".to_string() => Box::new(csv::make_module),
"_functools".to_string() => Box::new(functools::make_module),
"errno".to_string() => Box::new(errno::make_module),
"hashlib".to_string() => Box::new(hashlib::make_module),
"itertools".to_string() => Box::new(itertools::make_module),
"_io".to_string() => Box::new(io::make_module),
"json".to_string() => Box::new(json::make_module),
"marshal".to_string() => Box::new(marshal::make_module),
"math".to_string() => Box::new(math::make_module),
"_operator".to_string() => Box::new(operator::make_module),
"platform".to_string() => Box::new(platform::make_module),
"regex_crate".to_string() => Box::new(re::make_module),
"random".to_string() => Box::new(random::make_module),
"_string".to_string() => Box::new(string::make_module),
"struct".to_string() => Box::new(pystruct::make_module),
"_thread".to_string() => Box::new(thread::make_module),
"time".to_string() => Box::new(time_module::make_module),
"_weakref".to_string() => Box::new(weakref::make_module),
"_imp".to_string() => Box::new(imp::make_module),
"unicodedata".to_string() => Box::new(unicodedata::make_module),
"_warnings".to_string() => Box::new(warnings::make_module),
"array".to_owned() => Box::new(array::make_module) as StdlibInitFunc,
"binascii".to_owned() => Box::new(binascii::make_module),
"dis".to_owned() => Box::new(dis::make_module),
"_collections".to_owned() => Box::new(collections::make_module),
"_csv".to_owned() => Box::new(csv::make_module),
"_functools".to_owned() => Box::new(functools::make_module),
"errno".to_owned() => Box::new(errno::make_module),
"hashlib".to_owned() => Box::new(hashlib::make_module),
"itertools".to_owned() => Box::new(itertools::make_module),
"_io".to_owned() => Box::new(io::make_module),
"json".to_owned() => Box::new(json::make_module),
"marshal".to_owned() => Box::new(marshal::make_module),
"math".to_owned() => Box::new(math::make_module),
"_operator".to_owned() => Box::new(operator::make_module),
"platform".to_owned() => Box::new(platform::make_module),
"regex_crate".to_owned() => Box::new(re::make_module),
"_random".to_owned() => Box::new(random::make_module),
"_string".to_owned() => Box::new(string::make_module),
"struct".to_owned() => Box::new(pystruct::make_module),
"_thread".to_owned() => Box::new(thread::make_module),
"time".to_owned() => Box::new(time_module::make_module),
"_weakref".to_owned() => Box::new(weakref::make_module),
"_imp".to_owned() => Box::new(imp::make_module),
"unicodedata".to_owned() => Box::new(unicodedata::make_module),
"_warnings".to_owned() => Box::new(warnings::make_module),
};
// Insert parser related modules:
#[cfg(feature = "rustpython-parser")]
{
modules.insert(
"_ast".to_string(),
"_ast".to_owned(),
Box::new(ast::make_module) as StdlibInitFunc,
);
modules.insert("keyword".to_string(), Box::new(keyword::make_module));
modules.insert("tokenize".to_string(), Box::new(tokenize::make_module));
modules.insert("keyword".to_owned(), Box::new(keyword::make_module));
modules.insert("tokenize".to_owned(), Box::new(tokenize::make_module));
}
// Insert compiler related modules:
#[cfg(feature = "rustpython-compiler")]
{
modules.insert("symtable".to_string(), Box::new(symtable::make_module));
modules.insert("symtable".to_owned(), Box::new(symtable::make_module));
}
// disable some modules on WASM
#[cfg(not(target_arch = "wasm32"))]
{
modules.insert("_os".to_string(), Box::new(os::make_module));
modules.insert("_socket".to_string(), Box::new(socket::make_module));
modules.insert("_os".to_owned(), Box::new(os::make_module));
modules.insert("_socket".to_owned(), Box::new(socket::make_module));
modules.insert(
"_multiprocessing".to_string(),
"_multiprocessing".to_owned(),
Box::new(multiprocessing::make_module),
);
modules.insert("signal".to_string(), Box::new(signal::make_module));
modules.insert("select".to_string(), Box::new(select::make_module));
modules.insert("_subprocess".to_string(), Box::new(subprocess::make_module));
modules.insert("zlib".to_string(), Box::new(zlib::make_module));
modules.insert("signal".to_owned(), Box::new(signal::make_module));
modules.insert("select".to_owned(), Box::new(select::make_module));
modules.insert("_subprocess".to_owned(), Box::new(subprocess::make_module));
modules.insert("zlib".to_owned(), Box::new(zlib::make_module));
modules.insert(
"faulthandler".to_string(),
"faulthandler".to_owned(),
Box::new(faulthandler::make_module),
);
}
@@ -128,13 +128,13 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
// Unix-only
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
{
modules.insert("pwd".to_string(), Box::new(pwd::make_module));
modules.insert("pwd".to_owned(), Box::new(pwd::make_module));
}
// Windows-only
#[cfg(windows)]
{
modules.insert("_winapi".to_string(), Box::new(winapi::make_module));
modules.insert("_winapi".to_owned(), Box::new(winapi::make_module));
}
modules

View File

@@ -78,16 +78,15 @@ fn operator_compare_digest(
(Either::A(a), Either::A(b)) => {
if !a.as_str().is_ascii() || !b.as_str().is_ascii() {
return Err(vm.new_type_error(
"comparing strings with non-ASCII characters is not supported".to_string(),
"comparing strings with non-ASCII characters is not supported".to_owned(),
));
}
timing_safe_cmp(a.as_str().as_bytes(), b.as_str().as_bytes())
}
(Either::B(a), Either::B(b)) => a.with_ref(|a| b.with_ref(|b| timing_safe_cmp(a, b))),
_ => {
return Err(vm.new_type_error(
"unsupported operand types(s) or combination of types".to_string(),
))
return Err(vm
.new_type_error("unsupported operand types(s) or combination of types".to_owned()))
}
};
Ok(res)

View File

@@ -87,7 +87,7 @@ fn make_path(_vm: &VirtualMachine, path: PyStringRef, dir_fd: &DirFd) -> PyStrin
}
}
fn os_close(fileno: i64, _vm: &VirtualMachine) {
fn os_close(fileno: i64) {
//The File type automatically closes when it goes out of scope.
//To enable us to close these file descriptors (and hence prevent leaks)
//we seek to create the relevant File and simply let it pass out of scope!
@@ -312,7 +312,7 @@ fn os_access(path: PyStringRef, mode: u8, vm: &VirtualMachine) -> PyResult<bool>
let flags = AccessFlags::from_bits(mode).ok_or_else(|| {
vm.new_value_error(
"One of the flags is wrong, there are only 4 possibilities F_OK, R_OK, W_OK and X_OK"
.to_string(),
.to_owned(),
)
})?;
@@ -340,7 +340,7 @@ fn os_access(path: PyStringRef, mode: u8, vm: &VirtualMachine) -> PyResult<bool>
}
fn os_error(message: OptionalArg<PyStringRef>, vm: &VirtualMachine) -> PyResult {
let msg = message.map_or("".to_string(), |msg| msg.as_str().to_string());
let msg = message.map_or("".to_owned(), |msg| msg.as_str().to_owned());
Err(vm.new_os_error(msg))
}
@@ -519,12 +519,12 @@ struct FollowSymlinks {
}
impl DirEntryRef {
fn name(self, _vm: &VirtualMachine) -> String {
fn name(self) -> String {
self.entry.file_name().into_string().unwrap()
}
fn path(self, _vm: &VirtualMachine) -> String {
self.entry.path().to_str().unwrap().to_string()
fn path(self) -> String {
self.entry.path().to_str().unwrap().to_owned()
}
#[allow(clippy::match_bool)]
@@ -568,7 +568,7 @@ impl DirEntryRef {
fn stat(self, dir_fd: DirFd, follow_symlinks: FollowSymlinks, vm: &VirtualMachine) -> PyResult {
os_stat(
Either::A(self.path(vm).try_into_ref(vm)?),
Either::A(self.path().try_into_ref(vm)?),
dir_fd,
follow_symlinks,
vm,
@@ -610,23 +610,23 @@ impl ScandirIterator {
}
#[pymethod]
fn close(&self, _vm: &VirtualMachine) {
fn close(&self) {
self.exhausted.set(true);
}
#[pymethod(name = "__iter__")]
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn iter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
#[pymethod(name = "__enter__")]
fn enter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
fn enter(zelf: PyRef<Self>) -> PyRef<Self> {
zelf
}
#[pymethod(name = "__exit__")]
fn exit(zelf: PyRef<Self>, _args: PyFuncArgs, vm: &VirtualMachine) {
zelf.close(vm)
fn exit(zelf: PyRef<Self>, _args: PyFuncArgs) {
zelf.close()
}
}
@@ -814,7 +814,6 @@ fn os_stat(
_file: Either<PyStringRef, i64>,
_dir_fd: DirFd,
_follow_symlinks: FollowSymlinks,
_vm: &VirtualMachine,
) -> PyResult {
unimplemented!();
}
@@ -877,7 +876,7 @@ fn os_getcwd(vm: &VirtualMachine) -> PyResult<String> {
.as_path()
.to_str()
.unwrap()
.to_string())
.to_owned())
}
fn os_chdir(path: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
@@ -980,7 +979,7 @@ fn os_pipe2(flags: libc::c_int, vm: &VirtualMachine) -> PyResult<(RawFd, RawFd)>
}
#[cfg(unix)]
fn os_system(command: PyStringRef, _vm: &VirtualMachine) -> PyResult<i32> {
fn os_system(command: PyStringRef) -> PyResult<i32> {
use libc::system;
use std::ffi::CString;
@@ -1039,7 +1038,7 @@ fn os_cpu_count(vm: &VirtualMachine) -> PyObjectRef {
vm.new_int(cpu_count)
}
fn os_exit(code: i32, _vm: &VirtualMachine) {
fn os_exit(code: i32) {
std::process::exit(code)
}
@@ -1150,7 +1149,7 @@ fn os_urandom(size: usize, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
Ok(()) => Ok(buf),
Err(e) => match e.raw_os_error() {
Some(errno) => Err(convert_io_error(vm, io::Error::from_raw_os_error(errno))),
None => Err(vm.new_os_error("Getting random failed".to_string())),
None => Err(vm.new_os_error("Getting random failed".to_owned())),
},
}
}
@@ -1203,7 +1202,7 @@ macro_rules! suppress_iph {
}};
}
fn os_isatty(fd: i32, _vm: &VirtualMachine) -> bool {
fn os_isatty(fd: i32) -> bool {
unsafe { suppress_iph!(libc::isatty(fd)) != 0 }
}
@@ -1224,9 +1223,9 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
let ctx = &vm.ctx;
let os_name = if cfg!(windows) {
"nt".to_string()
"nt".to_owned()
} else {
"posix".to_string()
"posix".to_owned()
};
let environ = _os_environ(vm);
@@ -1235,8 +1234,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
ScandirIterator::extend_class(ctx, &scandir_iter);
let dir_entry = py_class!(ctx, "DirEntry", ctx.object(), {
"name" => ctx.new_property(DirEntryRef::name),
"path" => ctx.new_property(DirEntryRef::path),
"name" => ctx.new_readonly_getset("name", DirEntryRef::name),
"path" => ctx.new_readonly_getset("path", DirEntryRef::path),
"is_dir" => ctx.new_method(DirEntryRef::is_dir),
"is_file" => ctx.new_method(DirEntryRef::is_file),
"is_symlink" => ctx.new_method(DirEntryRef::is_symlink),

View File

@@ -15,7 +15,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
}
fn platform_python_implementation(_vm: &VirtualMachine) -> String {
"RustPython".to_string()
"RustPython".to_owned()
}
fn platform_python_version(_vm: &VirtualMachine) -> String {

View File

@@ -14,31 +14,31 @@ impl PyValue for Passwd {
type PasswdRef = PyRef<Passwd>;
impl PasswdRef {
fn pw_name(self, _vm: &VirtualMachine) -> String {
fn pw_name(self) -> String {
self.name.clone()
}
fn pw_passwd(self, _vm: &VirtualMachine) -> Option<String> {
fn pw_passwd(self) -> Option<String> {
self.passwd.clone()
}
fn pw_uid(self, _vm: &VirtualMachine) -> u32 {
fn pw_uid(self) -> u32 {
self.uid
}
fn pw_gid(self, _vm: &VirtualMachine) -> u32 {
fn pw_gid(self) -> u32 {
self.gid
}
fn pw_gecos(self, _vm: &VirtualMachine) -> Option<String> {
fn pw_gecos(self) -> Option<String> {
self.gecos.clone()
}
fn pw_dir(self, _vm: &VirtualMachine) -> String {
fn pw_dir(self) -> String {
self.dir.clone()
}
fn pw_shell(self, _vm: &VirtualMachine) -> String {
fn pw_shell(self) -> String {
self.shell.clone()
}
}
@@ -68,13 +68,13 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
let ctx = &vm.ctx;
let passwd_type = py_class!(ctx, "struct_passwd", ctx.object(), {
"pw_name" => ctx.new_property(PasswdRef::pw_name),
"pw_passwd" => ctx.new_property(PasswdRef::pw_passwd),
"pw_uid" => ctx.new_property(PasswdRef::pw_uid),
"pw_gid" => ctx.new_property(PasswdRef::pw_gid),
"pw_gecos" => ctx.new_property(PasswdRef::pw_gecos),
"pw_dir" => ctx.new_property(PasswdRef::pw_dir),
"pw_shell" => ctx.new_property(PasswdRef::pw_shell),
"pw_name" => ctx.new_readonly_getset("pw_name", PasswdRef::pw_name),
"pw_passwd" => ctx.new_readonly_getset("pw_passwd", PasswdRef::pw_passwd),
"pw_uid" => ctx.new_readonly_getset("pw_uid", PasswdRef::pw_uid),
"pw_gid" => ctx.new_readonly_getset("pw_gid", PasswdRef::pw_gid),
"pw_gecos" => ctx.new_readonly_getset("pw_gecos", PasswdRef::pw_gecos),
"pw_dir" => ctx.new_readonly_getset("pw_dir", PasswdRef::pw_dir),
"pw_shell" => ctx.new_readonly_getset("pw_shell", PasswdRef::pw_shell),
});
py_module!(vm, "pwd", {

View File

@@ -252,7 +252,7 @@ fn struct_pack(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
)))
}
} else {
Err(vm.new_type_error("First argument must be of str type".to_string()))
Err(vm.new_type_error("First argument must be of str type".to_owned()))
}
}
}

View File

@@ -1,46 +1,129 @@
//! Random module.
use rand::distributions::Distribution;
use rand_distr::Normal;
use std::cell::RefCell;
use crate::pyobject::{PyObjectRef, PyResult};
use crate::vm::VirtualMachine;
use num_bigint::{BigInt, Sign};
use num_traits::Signed;
use rand::RngCore;
use crate::function::OptionalOption;
use crate::obj::objint::PyIntRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue};
use crate::VirtualMachine;
mod mersenne;
#[derive(Debug)]
enum PyRng {
Std(rand::rngs::ThreadRng),
MT(Box<mersenne::MT19937>),
}
impl Default for PyRng {
fn default() -> Self {
PyRng::Std(rand::thread_rng())
}
}
impl RngCore for PyRng {
fn next_u32(&mut self) -> u32 {
match self {
Self::Std(s) => s.next_u32(),
Self::MT(m) => m.next_u32(),
}
}
fn next_u64(&mut self) -> u64 {
match self {
Self::Std(s) => s.next_u64(),
Self::MT(m) => m.next_u64(),
}
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
match self {
Self::Std(s) => s.fill_bytes(dest),
Self::MT(m) => m.fill_bytes(dest),
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
match self {
Self::Std(s) => s.try_fill_bytes(dest),
Self::MT(m) => m.try_fill_bytes(dest),
}
}
}
#[pyclass(name = "Random")]
#[derive(Debug)]
struct PyRandom {
rng: RefCell<PyRng>,
}
impl PyValue for PyRandom {
fn class(vm: &VirtualMachine) -> PyClassRef {
vm.class("_random", "Random")
}
}
#[pyimpl(flags(BASETYPE))]
impl PyRandom {
#[pyslot(new)]
fn new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
PyRandom {
rng: RefCell::new(PyRng::default()),
}
.into_ref_with_type(vm, cls)
}
#[pymethod]
fn random(&self) -> f64 {
mersenne::gen_res53(&mut *self.rng.borrow_mut())
}
#[pymethod]
fn seed(&self, n: OptionalOption<PyIntRef>) {
let new_rng = match n.flat_option() {
None => PyRng::default(),
Some(n) => {
let (_, mut key) = n.as_bigint().abs().to_u32_digits();
if cfg!(target_endian = "big") {
key.reverse();
}
PyRng::MT(Box::new(mersenne::MT19937::new_with_slice_seed(&key)))
}
};
*self.rng.borrow_mut() = new_rng;
}
#[pymethod]
fn getrandbits(&self, mut k: usize) -> BigInt {
let mut rng = self.rng.borrow_mut();
let mut gen_u32 = |k| rng.next_u32() >> (32 - k) as u32;
if k <= 32 {
return gen_u32(k).into();
}
let words = (k - 1) / 8 + 1;
let mut wordarray = vec![0u32; words];
let it = wordarray.iter_mut();
#[cfg(target_endian = "big")]
let it = it.rev();
for word in it {
*word = gen_u32(k);
k -= 32;
}
BigInt::from_slice(Sign::NoSign, &wordarray)
}
}
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
let ctx = &vm.ctx;
py_module!(vm, "random", {
"gauss" => ctx.new_function(random_normalvariate), // TODO: is this the same?
"normalvariate" => ctx.new_function(random_normalvariate),
"random" => ctx.new_function(random_random),
// "weibull", ctx.new_function(random_weibullvariate),
py_module!(vm, "_random", {
"Random" => PyRandom::make_class(ctx),
})
}
fn random_normalvariate(mu: f64, sigma: f64, vm: &VirtualMachine) -> PyResult<f64> {
let normal = Normal::new(mu, sigma).map_err(|rand_err| {
vm.new_exception_msg(
vm.ctx.exceptions.arithmetic_error.clone(),
format!("invalid normal distribution: {:?}", rand_err),
)
})?;
let value = normal.sample(&mut rand::thread_rng());
Ok(value)
}
fn random_random(_vm: &VirtualMachine) -> f64 {
rand::random()
}
/*
* TODO: enable this function:
fn random_weibullvariate(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(alpha, Some(vm.ctx.float_type())), (beta, Some(vm.ctx.float_type()))]);
let alpha = objfloat::get_value(alpha);
let beta = objfloat::get_value(beta);
let weibull = Weibull::new(alpha, beta);
let value = weibull.sample(&mut rand::thread_rng());
let py_value = vm.ctx.new_float(value);
Ok(py_value)
}
*/

View File

@@ -0,0 +1,211 @@
#![allow(clippy::unreadable_literal)]
/*
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/
// this was translated from c; all rights go to copyright holders listed above
// https://gist.github.com/coolreader18/b56d510f1b0551d2954d74ad289f7d2e
/* Period parameters */
const N: usize = 624;
const M: usize = 397;
const MATRIX_A: u32 = 0x9908b0dfu32; /* constant vector a */
const UPPER_MASK: u32 = 0x80000000u32; /* most significant w-r bits */
const LOWER_MASK: u32 = 0x7fffffffu32; /* least significant r bits */
pub struct MT19937 {
mt: [u32; N], /* the array for the state vector */
mti: usize, /* mti==N+1 means mt[N] is not initialized */
}
impl Default for MT19937 {
fn default() -> Self {
MT19937 {
mt: [0; N],
mti: N + 1,
}
}
}
impl std::fmt::Debug for MT19937 {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.pad("MT19937")
}
}
impl MT19937 {
pub fn new_with_slice_seed(init_key: &[u32]) -> Self {
let mut state = Self::default();
state.seed_slice(init_key);
state
}
/* initializes self.mt[N] with a seed */
fn seed(&mut self, s: u32) {
self.mt[0] = s;
self.mti = 1;
while self.mti < N {
self.mt[self.mti] = 1812433253u32
.wrapping_mul(self.mt[self.mti - 1] ^ (self.mt[self.mti - 1] >> 30))
+ self.mti as u32;
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array self.mt[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
self.mti += 1;
}
}
/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its length */
/* slight change for C++, 2004/2/26 */
pub fn seed_slice(&mut self, init_key: &[u32]) {
let mut i;
let mut j;
let mut k;
self.seed(19650218);
i = 1;
j = 0;
k = if N > init_key.len() {
N
} else {
init_key.len()
};
while k != 0 {
self.mt[i] = (self.mt[i]
^ ((self.mt[i - 1] ^ (self.mt[i - 1] >> 30)).wrapping_mul(1664525u32)))
+ init_key[j]
+ j as u32; /* non linear */
self.mt[i] &= 0xffffffffu32; /* for WORDSIZE > 32 machines */
i += 1;
j += 1;
if i >= N {
self.mt[0] = self.mt[N - 1];
i = 1;
}
if j >= init_key.len() {
j = 0;
}
k -= 1;
}
k = N - 1;
while k != 0 {
self.mt[i] = (self.mt[i]
^ ((self.mt[i - 1] ^ (self.mt[i - 1] >> 30)).wrapping_mul(1566083941u32)))
- i as u32; /* non linear */
self.mt[i] &= 0xffffffffu32; /* for WORDSIZE > 32 machines */
i += 1;
if i >= N {
self.mt[0] = self.mt[N - 1];
i = 1;
}
k -= 1;
}
self.mt[0] = 0x80000000u32; /* MSB is 1; assuring non-zero initial array */
}
/* generates a random number on [0,0xffffffff]-interval */
fn gen_u32(&mut self) -> u32 {
let mut y: u32;
let mag01 = |x| if (x & 0x1) == 1 { MATRIX_A } else { 0 };
/* mag01[x] = x * MATRIX_A for x=0,1 */
if self.mti >= N {
/* generate N words at one time */
if self.mti == N + 1
/* if seed() has not been called, */
{
self.seed(5489u32);
} /* a default initial seed is used */
for kk in 0..N - M {
y = (self.mt[kk] & UPPER_MASK) | (self.mt[kk + 1] & LOWER_MASK);
self.mt[kk] = self.mt[kk + M] ^ (y >> 1) ^ mag01(y);
}
for kk in N - M..N - 1 {
y = (self.mt[kk] & UPPER_MASK) | (self.mt[kk + 1] & LOWER_MASK);
self.mt[kk] = self.mt[kk.wrapping_add(M.wrapping_sub(N))] ^ (y >> 1) ^ mag01(y);
}
y = (self.mt[N - 1] & UPPER_MASK) | (self.mt[0] & LOWER_MASK);
self.mt[N - 1] = self.mt[M - 1] ^ (y >> 1) ^ mag01(y);
self.mti = 0;
}
y = self.mt[self.mti];
self.mti += 1;
/* Tempering */
y ^= y >> 11;
y ^= (y << 7) & 0x9d2c5680u32;
y ^= (y << 15) & 0xefc60000u32;
y ^= y >> 18;
y
}
}
/* generates a random number on [0,1) with 53-bit resolution*/
pub fn gen_res53<R: rand::RngCore>(rng: &mut R) -> f64 {
let a = rng.next_u32() >> 5;
let b = rng.next_u32() >> 6;
(a as f64 * 67108864.0 + b as f64) * (1.0 / 9007199254740992.0)
}
/* These real versions are due to Isaku Wada, 2002/01/09 added */
impl rand::RngCore for MT19937 {
fn next_u32(&mut self) -> u32 {
self.gen_u32()
}
fn next_u64(&mut self) -> u64 {
rand_core::impls::next_u64_via_u32(self)
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
rand_core::impls::fill_bytes_via_next(self, dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
self.fill_bytes(dest);
Ok(())
}
}

View File

@@ -266,7 +266,7 @@ fn do_split(
fn make_regex(vm: &VirtualMachine, pattern: &str, flags: PyRegexFlags) -> PyResult<PyPattern> {
let unicode = if flags.unicode && flags.ascii {
return Err(vm.new_value_error("ASCII and UNICODE flags are incompatible".to_string()));
return Err(vm.new_value_error("ASCII and UNICODE flags are incompatible".to_owned()));
} else {
!flags.ascii
};
@@ -283,7 +283,7 @@ fn make_regex(vm: &VirtualMachine, pattern: &str, flags: PyRegexFlags) -> PyResu
})?;
Ok(PyPattern {
regex: r,
pattern: pattern.to_string(),
pattern: pattern.to_owned(),
})
}
@@ -312,7 +312,7 @@ fn re_compile(
make_regex(vm, pattern.as_str(), flags)
}
fn re_escape(pattern: PyStringRef, _vm: &VirtualMachine) -> String {
fn re_escape(pattern: PyStringRef) -> String {
regex::escape(pattern.as_str())
}

View File

@@ -56,7 +56,7 @@ impl TryFromObject for Selectable {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let fno = RawFd::try_from_object(vm, obj.clone()).or_else(|_| {
let meth = vm.get_method_or_type_error(obj.clone(), "fileno", || {
"select arg must be an int or object with a fileno() method".to_string()
"select arg must be an int or object with a fileno() method".to_owned()
})?;
RawFd::try_from_object(vm, vm.invoke(&meth, vec![])?)
})?;
@@ -119,7 +119,7 @@ fn select_select(
});
if let Some(timeout) = timeout {
if timeout < 0.0 {
return Err(vm.new_value_error("timeout must be positive".to_string()));
return Err(vm.new_value_error("timeout must be positive".to_owned()));
}
}
let deadline = timeout.map(|s| super::time_module::get_time() + s);

Some files were not shown because too many files have changed in this diff Show More