From 8a3fb408dcc74adb4b89d8c4ea1b52c6f17de80b Mon Sep 17 00:00:00 2001 From: malkoG Date: Sun, 27 Oct 2019 01:27:34 +0900 Subject: [PATCH 01/26] Implement `random` module --- Lib/random.py | 778 ++++++++++++++++++++++++++++++++ tests/snippets/stdlib_random.py | 30 ++ vm/Cargo.toml | 2 +- vm/src/stdlib/mod.rs | 2 +- vm/src/stdlib/random.rs | 70 ++- 5 files changed, 878 insertions(+), 4 deletions(-) create mode 100644 Lib/random.py create mode 100644 tests/snippets/stdlib_random.py diff --git a/Lib/random.py b/Lib/random.py new file mode 100644 index 0000000000..3f2eb7696b --- /dev/null +++ b/Lib/random.py @@ -0,0 +1,778 @@ +"""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 +import os as _os + +__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<= 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) * _sqrt(u * c) + +## -------------------- 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/beta) + 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.perf_counter() + for i in range(n): + x = func(*args) + total += x + sqsum = sqsum + x*x + smallest = min(x, smallest) + largest = max(x, largest) + t1 = time.perf_counter() + 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 hasattr(_os, "fork"): + _os.register_at_fork(after_in_child=_inst.seed) + + +if __name__ == '__main__': + _test() diff --git a/tests/snippets/stdlib_random.py b/tests/snippets/stdlib_random.py new file mode 100644 index 0000000000..48bb623787 --- /dev/null +++ b/tests/snippets/stdlib_random.py @@ -0,0 +1,30 @@ +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 all([l == r for l, r in zip(left, right) ]) + +# random.choice +assert random.choice(left) == 5 + +# random.choices +expected = ['red', 'red', 'black', 'red', 'black', 'black'] +result = random.choices(['red', 'black', 'green'], [18, 18, 2], k=6) +assert all([l == r for l, r in zip(expected, result) ]) + +# random.sample +sampled = [2, 1, 0] +assert all([l == r for l, r in zip(random.sample(l, 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 diff --git a/vm/Cargo.toml b/vm/Cargo.toml index f404bb9cb1..1da5c9c2dc 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -30,7 +30,7 @@ num-traits = "0.2.8" num-integer = "0.1.41" num-rational = "0.2.2" num-iter = "0.1.39" -rand = "0.7" +rand = { version = "0.7", features = ["small_rng"] } rand_distr = "0.2" getrandom = "0.1" log = "0.4" diff --git a/vm/src/stdlib/mod.rs b/vm/src/stdlib/mod.rs index d3dd0e7329..52ae1a2c9d 100644 --- a/vm/src/stdlib/mod.rs +++ b/vm/src/stdlib/mod.rs @@ -78,7 +78,7 @@ pub fn get_module_inits() -> HashMap { "_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), + "_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), diff --git a/vm/src/stdlib/random.rs b/vm/src/stdlib/random.rs index 685088f6af..19716746fe 100644 --- a/vm/src/stdlib/random.rs +++ b/vm/src/stdlib/random.rs @@ -1,15 +1,81 @@ //! Random module. +use std::cell::RefCell; + +use num_bigint::{BigInt, Sign}; + use rand::distributions::Distribution; +use rand::{RngCore, SeedableRng}; +use rand::rngs::SmallRng; use rand_distr::Normal; -use crate::pyobject::{PyObjectRef, PyResult}; +use crate::function::OptionalArg; +use crate::obj::objtype::PyClassRef; +use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyValue, PyResult}; + use crate::vm::VirtualMachine; +#[pyclass(name = "Random")] +#[derive(Debug)] +struct PyRandom { + rng: RefCell +} + +impl PyValue for PyRandom { + fn class(vm: &VirtualMachine) -> PyClassRef { + vm.class("_random", "Random") + } +} + +#[pyimpl] +impl PyRandom { + #[pyslot(new)] + fn new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult> { + PyRandom { + rng: RefCell::new(SmallRng::from_entropy()) + }.into_ref_with_type(vm, cls) + } + + #[pymethod] + fn seed(&self, n: Option, vm: &VirtualMachine) -> PyResult { + let rng = match n { + None => SmallRng::from_entropy(), + Some(n) => { + let seed = n as u64; + SmallRng::seed_from_u64(seed) + } + }; + + *self.rng.borrow_mut() = rng; + + Ok(vm.ctx.none()) + } + + #[pymethod] + fn getrandbits(&self, k: usize, vm: &VirtualMachine) -> PyResult { + let bytes = (k - 1) / 8 + 1; + let mut bytearray = vec![0u8; bytes]; + self.rng.borrow_mut().fill_bytes(&mut bytearray); + + let bits = bytes % 8; + if bits > 0 { + bytearray[0] >>= 8 - bits; + } + + println!("{:?}", k); + println!("{:?}", bytearray); + + let result = BigInt::from_bytes_be(Sign::Plus, &bytearray); + Ok(vm.ctx.new_bigint(&result)) + } +} + pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let ctx = &vm.ctx; + let random_type = PyRandom::make_class(ctx); - py_module!(vm, "random", { + py_module!(vm, "_random", { + "Random" => random_type, "gauss" => ctx.new_function(random_normalvariate), // TODO: is this the same? "normalvariate" => ctx.new_function(random_normalvariate), "random" => ctx.new_function(random_random), From 908abef5da37f7c3540026adc7ab4a6b72ce74be Mon Sep 17 00:00:00 2001 From: malkoG Date: Sat, 14 Dec 2019 13:32:21 +0900 Subject: [PATCH 02/26] Apply code review for test snippet --- tests/snippets/stdlib_random.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/snippets/stdlib_random.py b/tests/snippets/stdlib_random.py index 48bb623787..81255ef5b8 100644 --- a/tests/snippets/stdlib_random.py +++ b/tests/snippets/stdlib_random.py @@ -9,20 +9,19 @@ left = list(range(10)) right = [2, 7, 3, 5, 8, 4, 6, 9, 0, 1] random.shuffle(left) - -assert all([l == r for l, r in zip(left, right) ]) +assert left == right # random.choice assert random.choice(left) == 5 # random.choices -expected = ['red', 'red', 'black', 'red', 'black', 'black'] +expected = ['red', 'green', 'red', 'black', 'black', 'red'] result = random.choices(['red', 'black', 'green'], [18, 18, 2], k=6) -assert all([l == r for l, r in zip(expected, result) ]) +assert expected == result # random.sample -sampled = [2, 1, 0] -assert all([l == r for l, r in zip(random.sample(l, 3), sampled) ]) +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, From a20b6bfaaa97e4a88d0d702aa65bfb5b6facaa33 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Fri, 31 Jan 2020 20:20:29 -0600 Subject: [PATCH 03/26] Implement _random using the MT19937 algorithm --- Cargo.lock | 11 +- vm/Cargo.toml | 4 +- vm/src/stdlib/random.rs | 162 ++++++++++++++----------- vm/src/stdlib/random/mersenne.rs | 202 +++++++++++++++++++++++++++++++ 4 files changed, 299 insertions(+), 80 deletions(-) create mode 100644 vm/src/stdlib/random/mersenne.rs diff --git a/Cargo.lock b/Cargo.lock index e9bdd29606..0b740e8158 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 1da5c9c2dc..fccb2dbcc5 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -30,8 +30,8 @@ num-traits = "0.2.8" num-integer = "0.1.41" num-rational = "0.2.2" num-iter = "0.1.39" -rand = { version = "0.7", features = ["small_rng"] } -rand_distr = "0.2" +rand = "0.7" +rand_core = "0.5" getrandom = "0.1" log = "0.4" rustpython-derive = {path = "../derive", version = "0.1.1"} diff --git a/vm/src/stdlib/random.rs b/vm/src/stdlib/random.rs index 19716746fe..46e58d45f4 100644 --- a/vm/src/stdlib/random.rs +++ b/vm/src/stdlib/random.rs @@ -3,22 +3,60 @@ use std::cell::RefCell; use num_bigint::{BigInt, Sign}; +use num_traits::Signed; +use rand::RngCore; -use rand::distributions::Distribution; -use rand::{RngCore, SeedableRng}; -use rand::rngs::SmallRng; -use rand_distr::Normal; - -use crate::function::OptionalArg; +use crate::function::OptionalOption; +use crate::obj::objint::PyIntRef; use crate::obj::objtype::PyClassRef; -use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyValue, PyResult}; +use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue}; +use crate::VirtualMachine; + +mod mersenne; + +#[derive(Debug)] +enum PyRng { + Std(rand::rngs::ThreadRng), + MT(mersenne::MT19937), +} -use crate::vm::VirtualMachine; +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 + rng: RefCell, } impl PyValue for PyRandom { @@ -27,86 +65,74 @@ impl PyValue for PyRandom { } } -#[pyimpl] +#[pyimpl(flags(BASETYPE))] impl PyRandom { #[pyslot(new)] fn new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult> { PyRandom { - rng: RefCell::new(SmallRng::from_entropy()) - }.into_ref_with_type(vm, cls) + rng: RefCell::new(PyRng::default()), + } + .into_ref_with_type(vm, cls) + } + + #[pymethod] + fn random(&self) -> f64 { + gen_res53(&mut *self.rng.borrow_mut()) } - #[pymethod] - fn seed(&self, n: Option, vm: &VirtualMachine) -> PyResult { - let rng = match n { - None => SmallRng::from_entropy(), + #[pymethod] + fn seed(&self, n: OptionalOption) { + let new_rng = match n.flat_option() { + None => PyRng::default(), Some(n) => { - let seed = n as u64; - SmallRng::seed_from_u64(seed) + let (_, mut key) = n.as_bigint().abs().to_u32_digits(); + if cfg!(target_endian = "big") { + key.reverse(); + } + PyRng::MT(mersenne::MT19937::new_with_slice_seed(&key)) } }; - - *self.rng.borrow_mut() = rng; - - Ok(vm.ctx.none()) + + *self.rng.borrow_mut() = new_rng; } #[pymethod] - fn getrandbits(&self, k: usize, vm: &VirtualMachine) -> PyResult { - let bytes = (k - 1) / 8 + 1; - let mut bytearray = vec![0u8; bytes]; - self.rng.borrow_mut().fill_bytes(&mut bytearray); - - let bits = bytes % 8; - if bits > 0 { - bytearray[0] >>= 8 - bits; + 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(); } - - println!("{:?}", k); - println!("{:?}", bytearray); - let result = BigInt::from_bytes_be(Sign::Plus, &bytearray); - Ok(vm.ctx.new_bigint(&result)) + 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; - let random_type = PyRandom::make_class(ctx); - py_module!(vm, "_random", { - "Random" => random_type, - "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), + "Random" => PyRandom::make_class(ctx), }) } -fn random_normalvariate(mu: f64, sigma: f64, vm: &VirtualMachine) -> PyResult { - 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) +// taken from the translated mersenne twister +/* generates a random number on [0,1) with 53-bit resolution*/ +fn gen_res53(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 */ diff --git a/vm/src/stdlib/random/mersenne.rs b/vm/src/stdlib/random/mersenne.rs new file mode 100644 index 0000000000..d4732a6ff5 --- /dev/null +++ b/vm/src/stdlib/random/mersenne.rs @@ -0,0 +1,202 @@ +/* + 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 & 0xffffffffu32; + 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.mt[self.mti] &= 0xffffffffu32; + /* for >32 bit machines */ + 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 + } +} + +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> { + Ok(self.fill_bytes(dest)) + } +} From 2fd9eb9a8a40b40d4b3d29631caf51230bbdaa16 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Fri, 31 Jan 2020 20:28:51 -0600 Subject: [PATCH 04/26] Add random.py from CPython 3.6 --- Lib/random.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/Lib/random.py b/Lib/random.py index 3f2eb7696b..61e881642c 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -41,12 +41,11 @@ 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 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 -import os as _os __all__ = ["Random","seed","random","uniform","randint","choice","sample", "randrange","shuffle","normalvariate","lognormvariate", @@ -225,12 +224,11 @@ def _randbelow(self, n, int=int, maxsize=1<= n: @@ -394,7 +392,7 @@ def triangular(self, low=0.0, high=1.0, mode=None): u = 1.0 - u c = 1.0 - c low, high = high, low - return low + (high - low) * _sqrt(u * c) + return low + (high - low) * (u * c) ** 0.5 ## -------------------- normal distribution -------------------- @@ -546,7 +544,7 @@ def gammavariate(self, alpha, beta): return x * beta elif alpha == 1.0: - # expovariate(1/beta) + # expovariate(1) u = random() while u <= 1e-7: u = random() @@ -707,14 +705,14 @@ def _test_generator(n, func, args): sqsum = 0.0 smallest = 1e10 largest = -1e10 - t0 = time.perf_counter() + 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.perf_counter() + t1 = time.time() print(round(t1-t0, 3), 'sec,', end=' ') avg = total/n stddev = _sqrt(sqsum/n - avg*avg) @@ -748,7 +746,7 @@ def _test(N=2000): _inst = Random() seed = _inst.seed -# random = _inst.random +random = _inst.random uniform = _inst.uniform triangular = _inst.triangular randint = _inst.randint @@ -770,9 +768,5 @@ def _test(N=2000): setstate = _inst.setstate getrandbits = _inst.getrandbits -if hasattr(_os, "fork"): - _os.register_at_fork(after_in_child=_inst.seed) - - if __name__ == '__main__': _test() From b40dcb7748508d6363da1092461a1afe5fdbdc22 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Fri, 31 Jan 2020 20:35:52 -0600 Subject: [PATCH 05/26] Use random.Random in tempfile --- Lib/tempfile.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 469a1bb3be..61462357c7 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -42,8 +42,7 @@ 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 @@ def __iter__(self): 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) From a762bf89d97fab01b579ba41fa34969d7d38e6ae Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 3 Feb 2020 18:27:35 -0600 Subject: [PATCH 06/26] Move gen_res53 to mersenne.rs --- vm/src/stdlib/random.rs | 11 +---------- vm/src/stdlib/random/mersenne.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/vm/src/stdlib/random.rs b/vm/src/stdlib/random.rs index 46e58d45f4..80acd18eb5 100644 --- a/vm/src/stdlib/random.rs +++ b/vm/src/stdlib/random.rs @@ -77,7 +77,7 @@ impl PyRandom { #[pymethod] fn random(&self) -> f64 { - gen_res53(&mut *self.rng.borrow_mut()) + mersenne::gen_res53(&mut *self.rng.borrow_mut()) } #[pymethod] @@ -127,12 +127,3 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "Random" => PyRandom::make_class(ctx), }) } - -// taken from the translated mersenne twister -/* generates a random number on [0,1) with 53-bit resolution*/ -fn gen_res53(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 */ diff --git a/vm/src/stdlib/random/mersenne.rs b/vm/src/stdlib/random/mersenne.rs index d4732a6ff5..d7e2efc2f9 100644 --- a/vm/src/stdlib/random/mersenne.rs +++ b/vm/src/stdlib/random/mersenne.rs @@ -186,6 +186,14 @@ impl MT19937 { } } +/* generates a random number on [0,1) with 53-bit resolution*/ +pub fn gen_res53(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() From 9abb2588493ead709534e5d4d6dde32182c56f21 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 3 Feb 2020 18:38:19 -0600 Subject: [PATCH 07/26] Fix clippy warnings --- vm/src/stdlib/random.rs | 4 ++-- vm/src/stdlib/random/mersenne.rs | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/vm/src/stdlib/random.rs b/vm/src/stdlib/random.rs index 80acd18eb5..b37cca4cc4 100644 --- a/vm/src/stdlib/random.rs +++ b/vm/src/stdlib/random.rs @@ -17,7 +17,7 @@ mod mersenne; #[derive(Debug)] enum PyRng { Std(rand::rngs::ThreadRng), - MT(mersenne::MT19937), + MT(Box), } impl Default for PyRng { @@ -89,7 +89,7 @@ impl PyRandom { if cfg!(target_endian = "big") { key.reverse(); } - PyRng::MT(mersenne::MT19937::new_with_slice_seed(&key)) + PyRng::MT(Box::new(mersenne::MT19937::new_with_slice_seed(&key))) } }; diff --git a/vm/src/stdlib/random/mersenne.rs b/vm/src/stdlib/random/mersenne.rs index d7e2efc2f9..b0f802ffa4 100644 --- a/vm/src/stdlib/random/mersenne.rs +++ b/vm/src/stdlib/random/mersenne.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unreadable_literal)] + /* A C-program for MT19937, with initialization improved 2002/1/26. Coded by Takuji Nishimura and Makoto Matsumoto. @@ -78,7 +80,7 @@ impl MT19937 { /* initializes self.mt[N] with a seed */ fn seed(&mut self, s: u32) { - self.mt[0] = s & 0xffffffffu32; + self.mt[0] = s; self.mti = 1; while self.mti < N { self.mt[self.mti] = 1812433253u32 @@ -88,8 +90,6 @@ impl MT19937 { /* In the previous versions, MSBs of the seed affect */ /* only MSBs of the array self.mt[]. */ /* 2002/01/09 modified by Makoto Matsumoto */ - self.mt[self.mti] &= 0xffffffffu32; - /* for >32 bit machines */ self.mti += 1; } } @@ -205,6 +205,7 @@ impl rand::RngCore for MT19937 { rand_core::impls::fill_bytes_via_next(self, dest) } fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } From c44f04b57e1c39694ce0687e0d55c0e7e6fc5adc Mon Sep 17 00:00:00 2001 From: Arnav Borborah Date: Tue, 4 Feb 2020 18:21:33 -0500 Subject: [PATCH 08/26] Fallback exit code to 0 in case of overflow --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 3833ee428d..013ef9de7f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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) { From 4c49185b52c24087a66518040ce4d6eb9ed7f51f Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Tue, 4 Feb 2020 20:36:11 -0600 Subject: [PATCH 09/26] Have wasm/demo's "test" npm script build the demo in release mode --- wasm/demo/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasm/demo/package.json b/wasm/demo/package.json index b05fe5c8a8..46c6aa340c 100644 --- a/wasm/demo/package.json +++ b/wasm/demo/package.json @@ -24,7 +24,7 @@ "dev": "webpack-dev-server -d", "build": "webpack", "dist": "webpack --mode production", - "test": "webpack && cd ../tests && pipenv run pytest" + "test": "webpack --mode production && cd ../tests && pipenv run pytest" }, "repository": { "type": "git", From 60037a2fbb80ffe61a0d443e193a15acb85e7dba Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Tue, 4 Feb 2020 21:43:06 -0600 Subject: [PATCH 10/26] Cache WASM dependencies --- .github/workflows/ci.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4659a9d465..089ee913a7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -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 From 1bac582921dc8cef7477958aea5d1cb583402f92 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Wed, 5 Feb 2020 19:15:18 +0900 Subject: [PATCH 11/26] &str::to_string -> &str::to_owned for literals --- benchmarks/bench.rs | 4 +- compiler/src/compile.rs | 22 +++++----- compiler/src/error.rs | 14 +++--- derive/src/compile_bytecode.rs | 2 +- derive/src/pyclass.rs | 2 +- examples/hello_embed.rs | 2 +- examples/mini_repl.rs | 2 +- examples/parse_folder.rs | 2 +- parser/src/error.rs | 2 +- parser/src/fstring.rs | 2 +- parser/src/lexer.rs | 12 +++--- parser/src/parser.rs | 2 +- src/main.rs | 2 +- src/shell.rs | 2 +- src/shell/rustyline_helper.rs | 2 +- vm/src/builtins.rs | 22 +++++----- vm/src/cformat.rs | 66 ++++++++++++++-------------- vm/src/dictdatatype.rs | 6 +-- vm/src/exceptions.rs | 2 +- vm/src/format.rs | 44 +++++++++---------- vm/src/frame.rs | 6 +-- vm/src/obj/objbool.rs | 8 ++-- vm/src/obj/objbytearray.rs | 14 +++--- vm/src/obj/objbyteinner.rs | 30 ++++++------- vm/src/obj/objbytes.rs | 4 +- vm/src/obj/objcode.rs | 2 +- vm/src/obj/objcomplex.rs | 6 +-- vm/src/obj/objcoroutine.rs | 2 +- vm/src/obj/objdict.rs | 12 +++--- vm/src/obj/objellipsis.rs | 4 +- vm/src/obj/objfloat.rs | 20 ++++----- vm/src/obj/objframe.rs | 4 +- vm/src/obj/objgenerator.rs | 2 +- vm/src/obj/objint.rs | 34 +++++++-------- vm/src/obj/objiter.rs | 6 +-- vm/src/obj/objlist.rs | 24 +++++------ vm/src/obj/objnone.rs | 2 +- vm/src/obj/objproperty.rs | 8 ++-- vm/src/obj/objrange.rs | 6 +-- vm/src/obj/objsequence.rs | 18 ++++---- vm/src/obj/objset.rs | 12 +++--- vm/src/obj/objslice.rs | 6 +-- vm/src/obj/objstr.rs | 70 +++++++++++++++--------------- vm/src/obj/objsuper.rs | 6 +-- vm/src/obj/objtuple.rs | 4 +- vm/src/obj/objtype.rs | 8 ++-- vm/src/obj/objweakproxy.rs | 4 +- vm/src/stdlib/binascii.rs | 6 +-- vm/src/stdlib/collections.rs | 10 ++--- vm/src/stdlib/csv.rs | 2 +- vm/src/stdlib/functools.rs | 2 +- vm/src/stdlib/hashlib.rs | 4 +- vm/src/stdlib/io.rs | 64 ++++++++++++++-------------- vm/src/stdlib/itertools.rs | 12 +++--- vm/src/stdlib/math.rs | 10 ++--- vm/src/stdlib/mod.rs | 78 +++++++++++++++++----------------- vm/src/stdlib/operator.rs | 7 ++- vm/src/stdlib/os.rs | 8 ++-- vm/src/stdlib/platform.rs | 2 +- vm/src/stdlib/pystruct.rs | 2 +- vm/src/stdlib/re.rs | 2 +- vm/src/stdlib/select.rs | 4 +- vm/src/stdlib/signal.rs | 2 +- vm/src/stdlib/socket.rs | 14 +++--- vm/src/stdlib/subprocess.rs | 12 +++--- vm/src/stdlib/time_module.rs | 4 +- vm/src/stdlib/unicodedata.rs | 8 ++-- vm/src/sysmodule.rs | 44 +++++++++---------- vm/src/version.rs | 2 +- vm/src/vm.rs | 4 +- wasm/lib/src/browser_module.rs | 4 +- wasm/lib/src/js_module.rs | 8 ++-- wasm/lib/src/vm_class.rs | 4 +- 73 files changed, 424 insertions(+), 431 deletions(-) diff --git a/benchmarks/bench.rs b/benchmarks/bench.rs index 60252ebe22..84c91be282 100644 --- a/benchmarks/bench.rs +++ b/benchmarks/bench.rs @@ -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, "".to_string()) { + let code = match vm.compile(source, compile::Mode::Single, "".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, "".to_string()) { + let code = match vm.compile(source, compile::Mode::Single, "".to_owned()) { Ok(code) => code, Err(e) => panic!("{:?}", e), }; diff --git a/compiler/src/compile.rs b/compiler/src/compile.rs index d02d3d3878..8ea3bc5207 100644 --- a/compiler/src/compile.rs +++ b/compiler/src/compile.rs @@ -88,7 +88,7 @@ fn with_compiler( ) -> Result { let mut compiler = Compiler::new(optimize); compiler.source_path = Some(source_path); - compiler.push_new_code_object("".to_string()); + compiler.push_new_code_object("".to_owned()); f(&mut compiler)?; let code = compiler.pop_code_object(); trace!("Compilation completed: {:?}", code); @@ -897,7 +897,7 @@ impl Compiler { // key: self.emit(Instruction::LoadConst { value: bytecode::Constant::String { - value: "return".to_string(), + value: "return".to_owned(), }, }); // value: @@ -989,11 +989,11 @@ impl Compiler { 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 Compiler { }, }); self.emit(Instruction::StoreName { - name: "__qualname__".to_string(), + name: "__qualname__".to_owned(), scope: bytecode::NameScope::Free, }); self.compile_statements(new_body)?; @@ -1090,7 +1090,7 @@ impl Compiler { self.emit(Instruction::Rotate { amount: 2 }); self.emit(Instruction::StoreAttr { - name: "__doc__".to_string(), + name: "__doc__".to_owned(), }); } @@ -1171,7 +1171,7 @@ impl Compiler { 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 { @@ -1732,7 +1732,7 @@ impl Compiler { func: FunctionContext::Function, }; - let name = "".to_string(); + let name = "".to_owned(); self.enter_function(&name, args)?; self.compile_expression(body)?; self.emit(Instruction::ReturnValue); @@ -1933,7 +1933,7 @@ impl Compiler { // Create magnificent function : self.push_output(CodeObject::new( Default::default(), - vec![".0".to_string()], + vec![".0".to_owned()], Varargs::None, vec![], Varargs::None, @@ -2264,8 +2264,8 @@ 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("".to_string()); + compiler.source_path = Some("source_path".to_owned()); + compiler.push_new_code_object("".to_owned()); let ast = parser::parse_program(&source.to_string()).unwrap(); let symbol_scope = make_symbol_table(&ast).unwrap(); compiler.compile_program(&ast, symbol_scope).unwrap(); diff --git a/compiler/src/error.rs b/compiler/src/error.rs index ae53a0032e..836e479add 100644 --- a/compiler/src/error.rs +++ b/compiler/src/error.rs @@ -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 { diff --git a/derive/src/compile_bytecode.rs b/derive/src/compile_bytecode.rs index e4382ee010..01f5226d60 100644 --- a/derive/src/compile_bytecode.rs +++ b/derive/src/compile_bytecode.rs @@ -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()), ) } } diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 17d76d6b42..fb6ac4b04e 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -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(), )) } } diff --git a/examples/hello_embed.rs b/examples/hello_embed.rs index 7db2174833..72b321a4fe 100644 --- a/examples/hello_embed.rs +++ b/examples/hello_embed.rs @@ -10,7 +10,7 @@ fn main() -> vm::pyobject::PyResult<()> { .compile( r#"print("Hello World!")"#, compiler::compile::Mode::Exec, - "".to_string(), + "".to_owned(), ) .map_err(|err| vm.new_syntax_error(&err))?; diff --git a/examples/mini_repl.rs b/examples/mini_repl.rs index 7a7da6088e..81a88c4fca 100644 --- a/examples/mini_repl.rs +++ b/examples/mini_repl.rs @@ -96,7 +96,7 @@ fn main() -> vm::pyobject::PyResult<()> { .compile( &input, compiler::compile::Mode::Single, - "".to_string(), + "".to_owned(), ) .map_err(|err| vm.new_syntax_error(&err)) .and_then(|code_obj| vm.run_code_obj(code_obj, scope.clone())) diff --git a/examples/parse_folder.rs b/examples/parse_folder.rs index ad0c5f8599..b0ab6251d9 100644 --- a/examples/parse_folder.rs +++ b/examples/parse_folder.rs @@ -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()), }, diff --git a/parser/src/error.rs b/parser/src/error.rs index 408fef3f6d..6afc4627b2 100644 --- a/parser/src/error.rs +++ b/parser/src/error.rs @@ -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) diff --git a/parser/src/fstring.rs b/parser/src/fstring.rs index c983c7d8c9..7ecd8a1239 100644 --- a/parser/src/fstring.rs +++ b/parser/src/fstring.rs @@ -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(), })), } ); diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs index 45448737ee..581b388a4a 100644 --- a/parser/src/lexer.rs +++ b/parser/src/lexer.rs @@ -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::().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, diff --git a/parser/src/parser.rs b/parser/src/parser.rs index 0f889c5af5..f3e994f10f 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -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), }], } diff --git a/src/main.rs b/src/main.rs index 013ef9de7f..9253e7f65f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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, "".to_string())?; + _run_string(vm, scope, &source, "".to_owned())?; Ok(()) } diff --git a/src/shell.rs b/src/shell.rs index af4f3c6cb8..aa31b3949e 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -21,7 +21,7 @@ enum ShellExecResult { } fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> ShellExecResult { - match vm.compile(source, compile::Mode::Single, "".to_string()) { + match vm.compile(source, compile::Mode::Single, "".to_owned()) { Ok(code) => { match vm.run_code_obj(code, scope.clone()) { Ok(value) => { diff --git a/src/shell/rustyline_helper.rs b/src/shell/rustyline_helper.rs index c06f50ba63..45b3ca3246 100644 --- a/src/shell/rustyline_helper.rs +++ b/src/shell/rustyline_helper.rs @@ -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()]))) } } diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 78538e0fbf..3f545a79ef 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -105,7 +105,7 @@ fn builtin_callable(obj: PyObjectRef, vm: &VirtualMachine) -> bool { fn builtin_chr(i: u32, vm: &VirtualMachine) -> PyResult { 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())), } } @@ -229,7 +229,7 @@ fn run_code( // Determine code object: let code_obj = match source { Either::A(string) => vm - .compile(string.as_str(), mode, "".to_string()) + .compile(string.as_str(), mode, "".to_owned()) .map_err(|err| vm.new_syntax_error(&err))?, Either::B(code_obj) => code_obj, }; @@ -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, 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 { diff --git a/vm/src/cformat.rs b/vm/src/cformat.rs index 7b1b07120a..8fa85a8ee2 100644 --- a/vm/src/cformat.rs +++ b/vm/src/cformat.rs @@ -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::() .unwrap() - .format_string("test".to_string()), - " test".to_string() + .format_string("test".to_owned()), + " test".to_owned() ); assert_eq!( "%-10s" .parse::() .unwrap() - .format_string("test".to_string()), - "test ".to_string() + .format_string("test".to_owned()), + "test ".to_owned() ); assert_eq!( "%#10x" .parse::() .unwrap() .format_number(&BigInt::from(0x1337)), - " 0x1337".to_string() + " 0x1337".to_owned() ); assert_eq!( "%-#10x" .parse::() .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::(), 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::() .unwrap() - .format_string("Hello, World!".to_string()), - " Hell".to_string() + .format_string("Hello, World!".to_owned()), + " Hell".to_owned() ); assert_eq!( "%-5.4s" .parse::() .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::() .unwrap() - .format_string("❤❤❤❤❤❤❤❤".to_string()), - "❤❤".to_string() + .format_string("❤❤❤❤❤❤❤❤".to_owned()), + "❤❤".to_owned() ); } @@ -765,56 +765,56 @@ mod tests { .parse::() .unwrap() .format_number(&BigInt::from(27)), - "00027".to_string() + "00027".to_owned() ); assert_eq!( "%+05d" .parse::() .unwrap() .format_number(&BigInt::from(27)), - "+0027".to_string() + "+0027".to_owned() ); assert_eq!( "%-d" .parse::() .unwrap() .format_number(&BigInt::from(-27)), - "-27".to_string() + "-27".to_owned() ); assert_eq!( "% d" .parse::() .unwrap() .format_number(&BigInt::from(27)), - " 27".to_string() + " 27".to_owned() ); assert_eq!( "% d" .parse::() .unwrap() .format_number(&BigInt::from(-27)), - "-27".to_string() + "-27".to_owned() ); assert_eq!( "%08x" .parse::() .unwrap() .format_number(&BigInt::from(0x1337)), - "00001337".to_string() + "00001337".to_owned() ); assert_eq!( "%#010x" .parse::() .unwrap() .format_number(&BigInt::from(0x1337)), - "0x00001337".to_string() + "0x00001337".to_owned() ); assert_eq!( "%-#010x" .parse::() .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::() .unwrap() .format_float(f64::from(-1.2345)) .ok(), - Some("-1.234500".to_string()) + Some("-1.234500".to_owned()) ); assert_eq!( "%f".parse::() .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::(); diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index 279a41f97e..d7dcb8fc34 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -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()); diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index ed616e9c11..208272bb19 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -347,7 +347,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), diff --git a/vm/src/format.rs b/vm/src/format.rs index 91c023a784..39c6ac2e7b 100644 --- a/vm/src/format.rs +++ b/vm/src/format.rs @@ -343,13 +343,13 @@ impl FormatSpec { let magnitude = num.abs(); let raw_magnitude_string_result: Result = 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)), @@ -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() }; @@ -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()), ], }); diff --git a/vm/src/frame.rs b/vm/src/frame.rs index a3ed5ffdb9..82b76b32d4 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -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(), )) } }, @@ -1390,7 +1390,7 @@ impl fmt::Debug for Frame { .iter() .map(|elem| { if elem.payload.as_any().is::() { - "\n > {frame}".to_string() + "\n > {frame}".to_owned() } else { format!("\n > {:?}", elem) } diff --git a/vm/src/obj/objbool.rs b/vm/src/obj/objbool.rs index 7c99fe6a10..a4b751c7e5 100644 --- a/vm/src/obj/objbool.rs +++ b/vm/src/obj/objbool.rs @@ -58,7 +58,7 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { 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()) ); } @@ -120,9 +120,9 @@ pub fn get_py_int(obj: &PyObjectRef) -> &PyInt { fn bool_repr(obj: bool, _vm: &VirtualMachine) -> 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())) } } diff --git a/vm/src/obj/objbytearray.rs b/vm/src/obj/objbytearray.rs index aa48bf6bb8..73e5d9d5d4 100644 --- a/vm/src/obj/objbytearray.rs +++ b/vm/src/obj/objbytearray.rs @@ -140,7 +140,7 @@ 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__")] @@ -331,7 +331,7 @@ impl PyByteArray { fn index(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult { 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 { 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); @@ -529,7 +529,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 +544,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,7 +556,7 @@ 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")] diff --git a/vm/src/obj/objbyteinner.rs b/vm/src/obj/objbyteinner.rs index 37c0616613..6a21f461fd 100644 --- a/vm/src/obj/objbyteinner.rs +++ b/vm/src/obj/objbyteinner.rs @@ -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())) } } @@ -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 { 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())), } } } diff --git a/vm/src/obj/objbytes.rs b/vm/src/obj/objbytes.rs index e38b76353b..99a9c6a26f 100644 --- a/vm/src/obj/objbytes.rs +++ b/vm/src/obj/objbytes.rs @@ -301,7 +301,7 @@ impl PyBytes { fn index(&self, options: ByteInnerFindOptions, vm: &VirtualMachine) -> PyResult { 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 { 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) } diff --git a/vm/src/obj/objcode.rs b/vm/src/obj/objcode.rs index f1598ad8f3..cfb634c8b1 100644 --- a/vm/src/obj/objcode.rs +++ b/vm/src/obj/objcode.rs @@ -44,7 +44,7 @@ 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 { diff --git a/vm/src/obj/objcomplex.rs b/vm/src/obj/objcomplex.rs index 1f90592364..24085c1412 100644 --- a/vm/src/obj/objcomplex.rs +++ b/vm/src/obj/objcomplex.rs @@ -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__")] diff --git a/vm/src/obj/objcoroutine.rs b/vm/src/obj/objcoroutine.rs index 4dad7d71d0..eb6f1faa2c 100644 --- a/vm/src/obj/objcoroutine.rs +++ b/vm/src/obj/objcoroutine.rs @@ -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) { diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs index c46c6a488e..d00e404a41 100644 --- a/vm/src/obj/objdict.rs +++ b/vm/src/obj/objdict.rs @@ -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, @@ -189,7 +189,7 @@ impl PyDictRef { format!("{{{}}}", str_parts.join(", ")) } else { - "{...}".to_string() + "{...}".to_owned() }; Ok(s) } @@ -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(&self, key: T, vm: &VirtualMachine) -> bool { @@ -528,7 +528,7 @@ macro_rules! dict_iterator { } 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) { diff --git a/vm/src/obj/objellipsis.rs b/vm/src/obj/objellipsis.rs index a836ca58e4..a8a22a4da0 100644 --- a/vm/src/obj/objellipsis.rs +++ b/vm/src/obj/objellipsis.rs @@ -22,9 +22,9 @@ fn ellipsis_new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult { } fn ellipsis_repr(_self: PyEllipsisRef, _vm: &VirtualMachine) -> String { - "Ellipsis".to_string() + "Ellipsis".to_owned() } fn ellipsis_reduce(_self: PyEllipsisRef, _vm: &VirtualMachine) -> String { - "Ellipsis".to_string() + "Ellipsis".to_owned() } diff --git a/vm/src/obj/objfloat.rs b/vm/src/obj/objfloat.rs index f6650ee4a7..2b660994b0 100644 --- a/vm/src/obj/objfloat.rs +++ b/vm/src/obj/objfloat.rs @@ -80,7 +80,7 @@ fn inner_div(v1: f64, v2: f64, vm: &VirtualMachine) -> PyResult { 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 { 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 { 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 { 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())) } } @@ -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()) }) } } @@ -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; diff --git a/vm/src/obj/objframe.rs b/vm/src/obj/objframe.rs index 46eaf52999..73067bd4bb 100644 --- a/vm/src/obj/objframe.rs +++ b/vm/src/obj/objframe.rs @@ -16,12 +16,12 @@ pub fn init(context: &PyContext) { impl FrameRef { #[pyslot] fn tp_new(_cls: FrameRef, vm: &VirtualMachine) -> PyResult { - 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 { - "".to_string() + "".to_owned() } #[pymethod] diff --git a/vm/src/obj/objgenerator.rs b/vm/src/obj/objgenerator.rs index 56927bd19d..a42519d7fe 100644 --- a/vm/src/obj/objgenerator.rs +++ b/vm/src/obj/objgenerator.rs @@ -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) { diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index d84f060333..a54833528c 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -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())) } } } @@ -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() { @@ -661,7 +661,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 +670,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 +702,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 +834,7 @@ pub fn get_value(obj: &PyObjectRef) -> &BigInt { pub fn try_float(int: &BigInt, vm: &VirtualMachine) -> PyResult { 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 { @@ -842,9 +842,9 @@ fn get_shift_amount(amount: &BigInt, vm: &VirtualMachine) -> PyResult { 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), } diff --git a/vm/src/obj/objiter.rs b/vm/src/obj/objiter.rs index 58bc61402d..2d98a04037 100644 --- a/vm/src/obj/objiter.rs +++ b/vm/src/obj/objiter.rs @@ -128,10 +128,10 @@ pub fn length_hint(vm: &VirtualMachine, iter: PyObjectRef) -> PyResult= 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)) } @@ -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 }; diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs index 4caf5f3577..5dc58f26cd 100644 --- a/vm/src/obj/objlist.rs +++ b/vm/src/obj/objlist.rs @@ -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())) } }, _ => { @@ -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 { @@ -459,14 +457,14 @@ impl PyList { } 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__")] @@ -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(()) diff --git a/vm/src/obj/objnone.rs b/vm/src/obj/objnone.rs index 57a6fcd8d5..51984923d0 100644 --- a/vm/src/obj/objnone.rs +++ b/vm/src/obj/objnone.rs @@ -44,7 +44,7 @@ impl PyNone { #[pymethod(name = "__repr__")] fn repr(&self, _vm: &VirtualMachine) -> PyResult { - Ok("None".to_string()) + Ok("None".to_owned()) } #[pymethod(name = "__bool__")] diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index 4660a3c650..d25feb227c 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -124,7 +124,7 @@ impl PyBuiltinDescriptor for PyProperty { vm.invoke(&getter, obj) } } else { - Err(vm.new_attribute_error("unreadable attribute".to_string())) + Err(vm.new_attribute_error("unreadable attribute".to_owned())) } } } @@ -149,7 +149,7 @@ impl PyProperty { if let Some(ref getter) = self.getter.as_ref() { vm.invoke(getter, obj) } else { - Err(vm.new_attribute_error("unreadable attribute".to_string())) + Err(vm.new_attribute_error("unreadable attribute".to_owned())) } } @@ -158,7 +158,7 @@ impl PyProperty { 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,7 +167,7 @@ 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())) } } diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs index 28998962ea..569dc4b472 100644 --- a/vm/src/obj/objrange.rs +++ b/vm/src/obj/objrange.rs @@ -148,7 +148,7 @@ impl PyRange { ) -> PyResult { 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) } @@ -318,7 +318,7 @@ 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())) } } @@ -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())), }, } } diff --git a/vm/src/obj/objsequence.rs b/vm/src/obj/objsequence.rs index aecfea2195..53bd6cacc9 100644 --- a/vm/src/obj/objsequence.rs +++ b/vm/src/obj/objsequence.rs @@ -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 })? .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()) }) }) } diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs index 6884cfa4cc..73e48ad247 100644 --- a/vm/src/obj/objset.rs +++ b/vm/src/obj/objset.rs @@ -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)) } } @@ -486,11 +486,11 @@ impl PySet { fn repr(zelf: PyRef, 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)) } @@ -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())) } } @@ -742,11 +742,11 @@ impl PyFrozenSet { fn repr(zelf: PyRef, 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)) } diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs index 42e3ba24aa..51ceb237da 100644 --- a/vm/src/obj/objslice.rs +++ b/vm/src/obj/objslice.rs @@ -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() { 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(), )) } } diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs index a95ea3c377..10e6eba69d 100644 --- a/vm/src/obj/objstr.rs +++ b/vm/src/obj/objstr.rs @@ -266,12 +266,13 @@ 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 @@ -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()) }) } @@ -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())), }, } } @@ -786,7 +787,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 { @@ -869,10 +870,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 +889,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())) } } @@ -908,8 +909,8 @@ impl PyString { 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) } @@ -927,8 +928,8 @@ impl PyString { 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) @@ -1001,9 +1002,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())) } } @@ -1381,20 +1381,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 +1415,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 +1424,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 +1454,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 +1465,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(), )); } @@ -1511,7 +1509,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 +1529,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) @@ -1568,7 +1566,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 +1576,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) @@ -1609,7 +1607,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) => { diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs index ba8b596645..c47c64057c 100644 --- a/vm/src/obj/objsuper.rs +++ b/vm/src/obj/objsuper.rs @@ -39,7 +39,7 @@ impl PySuper { let class_type_str = if let Ok(type_class) = self.typ.clone().downcast::() { type_class.name.clone() } else { - "NONE".to_string() + "NONE".to_owned() }; match self.obj_type.clone().downcast::() { Ok(obj_class_typ) => format!( @@ -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())? diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs index 154251f032..27be3b3607 100644 --- a/vm/src/obj/objtuple.rs +++ b/vm/src/obj/objtuple.rs @@ -185,7 +185,7 @@ impl PyTuple { format!("({})", str_parts.join(", ")) } } else { - "(...)".to_string() + "(...)".to_owned() }; Ok(s) } @@ -215,7 +215,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__")] diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index 1e61c6e4db..e7465e6ccf 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -87,7 +87,7 @@ impl PyClassRef { } fn _set_mro(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - Err(vm.new_attribute_error("read-only attribute".to_string())) + Err(vm.new_attribute_error("read-only attribute".to_owned())) } #[pyproperty(magic)] @@ -261,7 +261,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,7 +322,7 @@ 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) @@ -408,7 +408,7 @@ fn type_dict_setter( vm: &VirtualMachine, ) -> PyResult<()> { Err(vm.new_not_implemented_error( - "Setting __dict__ attribute on a type isn't yet implemented".to_string(), + "Setting __dict__ attribute on a type isn't yet implemented".to_owned(), )) } diff --git a/vm/src/obj/objweakproxy.rs b/vm/src/obj/objweakproxy.rs index d4422868fe..d10f9fcc4a 100644 --- a/vm/src/obj/objweakproxy.rs +++ b/vm/src/obj/objweakproxy.rs @@ -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(), )), } } diff --git a/vm/src/stdlib/binascii.rs b/vm/src/stdlib/binascii.rs index 782d902e0c..6b4469660d 100644 --- a/vm/src/stdlib/binascii.rs +++ b/vm/src/stdlib/binascii.rs @@ -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(), )) } } @@ -79,7 +79,7 @@ fn unhex_nibble(c: u8) -> Option { fn binascii_unhexlify(data: SerializedData, vm: &VirtualMachine) -> PyResult> { 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::::with_capacity(hex_bytes.len() / 2); @@ -87,7 +87,7 @@ fn binascii_unhexlify(data: SerializedData, vm: &VirtualMachine) -> PyResult PyResul if let Ok(iterable) = PyIterable::::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())) } } diff --git a/vm/src/stdlib/functools.rs b/vm/src/stdlib/functools.rs index 283426b33c..a1164a71e8 100644 --- a/vm/src/stdlib/functools.rs +++ b/vm/src/stdlib/functools.rs @@ -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 diff --git a/vm/src/stdlib/hashlib.rs b/vm/src/stdlib/hashlib.rs index 5e4b493527..4b8f6b4122 100644 --- a/vm/src/stdlib/hashlib.rs +++ b/vm/src/stdlib/hashlib.rs @@ -158,11 +158,11 @@ fn sha3_512(data: OptionalArg, vm: &VirtualMachine) -> PyResult, vm: &VirtualMachine) -> PyResult { - Err(vm.new_not_implemented_error("shake256".to_string())) + Err(vm.new_not_implemented_error("shake256".to_owned())) } fn shake256(_data: OptionalArg, vm: &VirtualMachine) -> PyResult { - Err(vm.new_not_implemented_error("shake256".to_string())) + Err(vm.new_not_implemented_error("shake256".to_owned())) } fn blake2b(data: OptionalArg, vm: &VirtualMachine) -> PyResult { diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index f40e214755..ee4ec13d45 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -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,7 +145,7 @@ 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())), } } @@ -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 { 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())), } } @@ -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, 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,7 +267,7 @@ 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())), } } @@ -282,7 +282,7 @@ impl PyBytesIORef { fn readline(self, vm: &VirtualMachine) -> PyResult> { 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())), } } @@ -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,7 +428,7 @@ 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(()) @@ -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())), } }; @@ -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 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() ); } } @@ -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( @@ -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()) ); } @@ -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()) ); } diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index e2688b0639..79253a36d9 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -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 { @@ -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(); @@ -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(); @@ -1161,11 +1161,11 @@ impl PyItertoolsPermutations { Some(r) => { let val = r .payload::() - .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() } diff --git a/vm/src/stdlib/math.rs b/vm/src/stdlib/math.rs index e5e27e446b..608b968a14 100644 --- a/vm/src/stdlib/math.rs +++ b/vm/src/stdlib/math.rs @@ -72,7 +72,7 @@ fn math_isclose(args: IsCloseArgs, vm: &VirtualMachine) -> PyResult { }; 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 { @@ -273,7 +273,7 @@ fn math_gcd(a: PyIntRef, b: PyIntRef, _vm: &VirtualMachine) -> BigInt { fn math_factorial(value: PyIntRef, vm: &VirtualMachine) -> PyResult { 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)); } @@ -306,7 +306,7 @@ fn math_nextafter(x: IntoPyFloat, y: IntoPyFloat) -> PyResult { #[cfg(target_arch = "wasm32")] fn math_nextafter(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult { - 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 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) } diff --git a/vm/src/stdlib/mod.rs b/vm/src/stdlib/mod.rs index 52ae1a2c9d..6baf8813f4 100644 --- a/vm/src/stdlib/mod.rs +++ b/vm/src/stdlib/mod.rs @@ -62,65 +62,65 @@ pub type StdlibInitFunc = Box PyObjectRef>; pub fn get_module_inits() -> HashMap { #[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 { // 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 diff --git a/vm/src/stdlib/operator.rs b/vm/src/stdlib/operator.rs index 103a49f4f0..11606cfe87 100644 --- a/vm/src/stdlib/operator.rs +++ b/vm/src/stdlib/operator.rs @@ -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) diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 0c8056ec6b..a5b35ecacd 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -340,7 +340,7 @@ fn os_access(path: PyStringRef, mode: u8, vm: &VirtualMachine) -> PyResult } fn os_error(message: OptionalArg, 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_string()); Err(vm.new_os_error(msg)) } @@ -1150,7 +1150,7 @@ fn os_urandom(size: usize, vm: &VirtualMachine) -> PyResult> { 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())), }, } } @@ -1224,9 +1224,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); diff --git a/vm/src/stdlib/platform.rs b/vm/src/stdlib/platform.rs index 869e9bb914..26f4949273 100644 --- a/vm/src/stdlib/platform.rs +++ b/vm/src/stdlib/platform.rs @@ -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 { diff --git a/vm/src/stdlib/pystruct.rs b/vm/src/stdlib/pystruct.rs index 7eec764f5c..34baea2987 100644 --- a/vm/src/stdlib/pystruct.rs +++ b/vm/src/stdlib/pystruct.rs @@ -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())) } } } diff --git a/vm/src/stdlib/re.rs b/vm/src/stdlib/re.rs index a0a5141d48..9de904e414 100644 --- a/vm/src/stdlib/re.rs +++ b/vm/src/stdlib/re.rs @@ -266,7 +266,7 @@ fn do_split( fn make_regex(vm: &VirtualMachine, pattern: &str, flags: PyRegexFlags) -> PyResult { 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 }; diff --git a/vm/src/stdlib/select.rs b/vm/src/stdlib/select.rs index 836a172b95..0423ae43dc 100644 --- a/vm/src/stdlib/select.rs +++ b/vm/src/stdlib/select.rs @@ -56,7 +56,7 @@ impl TryFromObject for Selectable { fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { 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); diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index e266e3d0b5..62a388ac81 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -55,7 +55,7 @@ fn signal(signalnum: i32, handler: PyObjectRef, vm: &VirtualMachine) -> PyResult let old = unsafe { libc::signal(signalnum, sig_handler) }; if old == SIG_ERR { - return Err(vm.new_os_error("Failed to set signal".to_string())); + return Err(vm.new_os_error("Failed to set signal".to_owned())); } #[cfg(all(unix, not(target_os = "redox")))] { diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index 9ea6636529..220d01a8b4 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -332,7 +332,7 @@ impl PySocket { }, _ => { return Err( - vm.new_type_error("expected the value arg xor the optlen arg".to_string()) + vm.new_type_error("expected the value arg xor the optlen arg".to_owned()) ); } }; @@ -351,7 +351,7 @@ impl PySocket { c::SHUT_RDWR => Shutdown::Both, _ => { return Err( - vm.new_value_error("`how` must be SHUT_RD, SHUT_WR, or SHUT_RDWR".to_string()) + vm.new_value_error("`how` must be SHUT_RD, SHUT_WR, or SHUT_RDWR".to_owned()) ) } }; @@ -390,7 +390,7 @@ impl TryFromObject for Address { fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { let tuple = PyTupleRef::try_from_object(vm, obj)?; if tuple.as_slice().len() != 2 { - Err(vm.new_type_error("Address tuple should have only 2 values".to_string())) + Err(vm.new_type_error("Address tuple should have only 2 values".to_owned())) } else { let host = PyStringRef::try_from_object(vm, tuple.as_slice()[0].clone())?; let host = if host.as_str().is_empty() { @@ -434,12 +434,12 @@ fn socket_inet_aton(ip_string: PyStringRef, vm: &VirtualMachine) -> PyResult { .as_str() .parse::() .map(|ip_addr| vm.ctx.new_bytes(ip_addr.octets().to_vec())) - .map_err(|_| vm.new_os_error("illegal IP address string passed to inet_aton".to_string())) + .map_err(|_| vm.new_os_error("illegal IP address string passed to inet_aton".to_owned())) } fn socket_inet_ntoa(packed_ip: PyBytesRef, vm: &VirtualMachine) -> PyResult { if packed_ip.len() != 4 { - return Err(vm.new_os_error("packed IP wrong length for inet_ntoa".to_string())); + return Err(vm.new_os_error("packed IP wrong length for inet_ntoa".to_owned())); } let ip_num = BigEndian::read_u32(&packed_ip); Ok(vm.new_str(Ipv4Addr::from(ip_num).to_string())) @@ -545,7 +545,7 @@ where let error_type = vm.class("_socket", "gaierror"); Err(vm.new_exception_msg( error_type, - "nodename nor servname provided, or not known".to_string(), + "nodename nor servname provided, or not known".to_owned(), )) } else { Ok(sock_addrs.next().unwrap().into()) @@ -599,7 +599,7 @@ fn invalid_sock() -> Socket { fn convert_sock_error(vm: &VirtualMachine, err: io::Error) -> PyBaseExceptionRef { if err.kind() == io::ErrorKind::TimedOut { let socket_timeout = vm.class("_socket", "timeout"); - vm.new_exception_msg(socket_timeout, "Timed out".to_string()) + vm.new_exception_msg(socket_timeout, "Timed out".to_owned()) } else { convert_io_error(vm, err) } diff --git a/vm/src/stdlib/subprocess.rs b/vm/src/stdlib/subprocess.rs index b933ab14ce..57ddfc780b 100644 --- a/vm/src/stdlib/subprocess.rs +++ b/vm/src/stdlib/subprocess.rs @@ -55,7 +55,7 @@ impl IntoPyObject for subprocess::ExitStatus { subprocess::ExitStatus::Exited(status) => status as i32, subprocess::ExitStatus::Signaled(status) => -i32::from(status), subprocess::ExitStatus::Other(status) => status as i32, - _ => return Err(vm.new_os_error("Unknown exist status".to_string())), + _ => return Err(vm.new_os_error("Unknown exist status".to_owned())), }; Ok(vm.new_int(status)) } @@ -153,22 +153,22 @@ impl PopenRef { .map_err(|s| vm.new_os_error(format!("Could not start program: {}", s)))?; if timeout.is_none() { let timeout_expired = vm.try_class("_subprocess", "TimeoutExpired")?; - Err(vm.new_exception_msg(timeout_expired, "Timeout".to_string())) + Err(vm.new_exception_msg(timeout_expired, "Timeout".to_owned())) } else { Ok(()) } } fn stdin(self, vm: &VirtualMachine) -> PyResult { - convert_to_file_io(&self.process.borrow().stdin, "wb".to_string(), vm) + convert_to_file_io(&self.process.borrow().stdin, "wb".to_owned(), vm) } fn stdout(self, vm: &VirtualMachine) -> PyResult { - convert_to_file_io(&self.process.borrow().stdout, "rb".to_string(), vm) + convert_to_file_io(&self.process.borrow().stdout, "rb".to_owned(), vm) } fn stderr(self, vm: &VirtualMachine) -> PyResult { - convert_to_file_io(&self.process.borrow().stderr, "rb".to_string(), vm) + convert_to_file_io(&self.process.borrow().stderr, "rb".to_owned(), vm) } fn terminate(self, vm: &VirtualMachine) -> PyResult<()> { @@ -202,7 +202,7 @@ impl PopenRef { communicator.read().map_err(|err| { if err.error.kind() == ErrorKind::TimedOut { let timeout_expired = vm.try_class("_subprocess", "TimeoutExpired").unwrap(); - vm.new_exception_msg(timeout_expired, "Timeout".to_string()) + vm.new_exception_msg(timeout_expired, "Timeout".to_owned()) } else { convert_io_error(vm, err.error) } diff --git a/vm/src/stdlib/time_module.rs b/vm/src/stdlib/time_module.rs index fc9ce6b1e2..c51354a163 100644 --- a/vm/src/stdlib/time_module.rs +++ b/vm/src/stdlib/time_module.rs @@ -194,7 +194,7 @@ impl PyStructTime { } fn to_date_time(&self, vm: &VirtualMachine) -> PyResult { - let invalid = || vm.new_value_error("invalid struct_time parameter".to_string()); + let invalid = || vm.new_value_error("invalid struct_time parameter".to_owned()); macro_rules! field { ($field:ident) => { TryFromObject::try_from_object(vm, self.$field.clone())? @@ -225,7 +225,7 @@ impl TryFromObject for PyStructTime { let seq = vm.extract_elements::(&seq)?; if seq.len() != 9 { return Err( - vm.new_type_error("time.struct_time() takes a sequence of length 9".to_string()) + vm.new_type_error("time.struct_time() takes a sequence of length 9".to_owned()) ); } let mut i = seq.into_iter(); diff --git a/vm/src/stdlib/unicodedata.rs b/vm/src/stdlib/unicodedata.rs index 077b687a79..9507d337fb 100644 --- a/vm/src/stdlib/unicodedata.rs +++ b/vm/src/stdlib/unicodedata.rs @@ -84,7 +84,7 @@ impl PyUCD { fn extract_char(&self, character: PyStringRef, vm: &VirtualMachine) -> PyResult> { let c = character.as_str().chars().exactly_one().map_err(|_| { - vm.new_type_error("argument must be an unicode character, not str".to_string()) + vm.new_type_error("argument must be an unicode character, not str".to_owned()) })?; if self.check_age(c) { @@ -132,9 +132,7 @@ impl PyUCD { } match default { OptionalArg::Present(obj) => Ok(obj), - OptionalArg::Missing => { - Err(vm.new_value_error("character name not found!".to_string())) - } + OptionalArg::Missing => Err(vm.new_value_error("character name not found!".to_owned())), } } @@ -160,7 +158,7 @@ impl PyUCD { "NFKC" => text.nfkc().collect::(), "NFD" => text.nfd().collect::(), "NFKD" => text.nfkd().collect::(), - _ => return Err(vm.new_value_error("invalid normalization form".to_string())), + _ => return Err(vm.new_value_error("invalid normalization form".to_owned())), }; Ok(normalized_text) diff --git a/vm/src/sysmodule.rs b/vm/src/sysmodule.rs index 3570110c03..072fa59b88 100644 --- a/vm/src/sysmodule.rs +++ b/vm/src/sysmodule.rs @@ -35,7 +35,7 @@ fn executable(ctx: &PyContext) -> PyObjectRef { fn getframe(offset: OptionalArg, vm: &VirtualMachine) -> PyResult { let offset = offset.into_option().unwrap_or(0); if offset > vm.frames.borrow().len() - 1 { - return Err(vm.new_value_error("call stack is not deep enough".to_string())); + return Err(vm.new_value_error("call stack is not deep enough".to_owned())); } let idx = vm.frames.borrow().len() - offset - 1; let frame = &vm.frames.borrow()[idx]; @@ -108,21 +108,21 @@ fn sys_getsizeof(obj: PyObjectRef, _vm: &VirtualMachine) -> usize { fn sys_getfilesystemencoding(_vm: &VirtualMachine) -> String { // TODO: implement non-utf-8 mode. - "utf-8".to_string() + "utf-8".to_owned() } fn sys_getdefaultencoding(_vm: &VirtualMachine) -> String { - "utf-8".to_string() + "utf-8".to_owned() } #[cfg(not(windows))] fn sys_getfilesystemencodeerrors(_vm: &VirtualMachine) -> String { - "surrogateescape".to_string() + "surrogateescape".to_owned() } #[cfg(windows)] fn sys_getfilesystemencodeerrors(_vm: &VirtualMachine) -> String { - "surrogatepass".to_string() + "surrogatepass".to_owned() } fn sys_getprofile(vm: &VirtualMachine) -> PyObjectRef { @@ -190,7 +190,7 @@ fn sys_exc_info(vm: &VirtualMachine) -> PyObjectRef { fn sys_git_info(vm: &VirtualMachine) -> PyObjectRef { vm.ctx.new_tuple(vec![ - vm.ctx.new_str("RustPython".to_string()), + vm.ctx.new_str("RustPython".to_owned()), vm.ctx.new_str(version::get_git_identifier()), vm.ctx.new_str(version::get_git_revision()), ]) @@ -216,8 +216,8 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR // TODO Add crate version to this namespace let implementation = py_namespace!(vm, { - "name" => ctx.new_str("rustpython".to_string()), - "cache_tag" => ctx.new_str("rustpython-01".to_string()), + "name" => ctx.new_str("rustpython".to_owned()), + "cache_tag" => ctx.new_str("rustpython-01".to_owned()), }); let path = ctx.new_list( @@ -229,27 +229,27 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR ); let platform = if cfg!(target_os = "linux") { - "linux".to_string() + "linux".to_owned() } else if cfg!(target_os = "macos") { - "darwin".to_string() + "darwin".to_owned() } else if cfg!(target_os = "windows") { - "win32".to_string() + "win32".to_owned() } else if cfg!(target_os = "android") { // Linux as well. see https://bugs.python.org/issue32637 - "linux".to_string() + "linux".to_owned() } else { - "unknown".to_string() + "unknown".to_owned() }; - let framework = "".to_string(); + let framework = "".to_owned(); // https://doc.rust-lang.org/reference/conditional-compilation.html#target_endian let bytorder = if cfg!(target_endian = "little") { - "little".to_string() + "little".to_owned() } else if cfg!(target_endian = "big") { - "big".to_string() + "big".to_owned() } else { - "unknown".to_string() + "unknown".to_owned() }; let copyright = "Copyright (c) 2019 RustPython Team"; @@ -324,8 +324,8 @@ setrecursionlimit() -- set the max recursion depth for the interpreter settrace() -- set the global debug tracing function "; let mut module_names: Vec = vm.stdlib_inits.borrow().keys().cloned().collect(); - module_names.push("sys".to_string()); - module_names.push("builtins".to_string()); + module_names.push("sys".to_owned()); + module_names.push("builtins".to_owned()); module_names.sort(); let builtin_module_names = ctx.new_tuple( module_names @@ -361,8 +361,8 @@ settrace() -- set the global debug tracing function "maxunicode" => ctx.new_int(0x0010_FFFF), "maxsize" => ctx.new_int(std::isize::MAX), "path" => path, - "ps1" => ctx.new_str(">>>>> ".to_string()), - "ps2" => ctx.new_str("..... ".to_string()), + "ps1" => ctx.new_str(">>>>> ".to_owned()), + "ps2" => ctx.new_str("..... ".to_owned()), "__doc__" => ctx.new_str(sys_doc.to_string()), "_getframe" => ctx.new_function(getframe), "modules" => modules.clone(), @@ -386,7 +386,7 @@ settrace() -- set the global debug tracing function "exec_prefix" => ctx.new_str(exec_prefix.to_string()), "base_exec_prefix" => ctx.new_str(base_exec_prefix.to_string()), "exit" => ctx.new_function(sys_exit), - "abiflags" => ctx.new_str("".to_string()), + "abiflags" => ctx.new_str("".to_owned()), }); modules.set_item("sys", module.clone(), vm).unwrap(); diff --git a/vm/src/version.rs b/vm/src/version.rs index 77ca12545e..c14f6c2943 100644 --- a/vm/src/version.rs +++ b/vm/src/version.rs @@ -59,7 +59,7 @@ pub fn get_build_info() -> String { format!( "{id}{sep}{revision}, {date:.20}, {time:.9}", id = if git_identifier.is_empty() { - "default".to_string() + "default".to_owned() } else { git_identifier }, diff --git a/vm/src/vm.rs b/vm/src/vm.rs index fa405e8073..7ea7215fbc 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -563,7 +563,7 @@ impl VirtualMachine { None => { let import_func = self .get_attribute(self.builtins.clone(), "__import__") - .map_err(|_| self.new_import_error("__import__ not found".to_string()))?; + .map_err(|_| self.new_import_error("__import__ not found".to_owned()))?; let (locals, globals) = if let Some(frame) = self.current_frame() { ( @@ -1213,7 +1213,7 @@ impl VirtualMachine { if let Some(hash_value) = hash_obj.payload_if_subclass::(self) { Ok(hash_value.hash(self)) } else { - Err(self.new_type_error("__hash__ method should return an integer".to_string())) + Err(self.new_type_error("__hash__ method should return an integer".to_owned())) } } diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs index 8e7e169f8c..eefc39552c 100644 --- a/wasm/lib/src/browser_module.rs +++ b/wasm/lib/src/browser_module.rs @@ -328,7 +328,7 @@ fn browser_load_module(module: PyStringRef, path: PyStringRef, vm: &VirtualMachi .expect("that the vm is valid when the promise resolves"); let vm = &stored_vm.vm; let resp_text = text.as_string().unwrap(); - let res = import_file(vm, module.as_str(), "WEB".to_string(), resp_text); + let res = import_file(vm, module.as_str(), "WEB".to_owned(), resp_text); match res { Ok(_) => Ok(JsValue::null()), Err(err) => Err(convert::py_err_to_js_err(vm, &err)), @@ -370,7 +370,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { pub fn setup_browser_module(vm: &VirtualMachine) { vm.stdlib_inits .borrow_mut() - .insert("_browser".to_string(), Box::new(make_module)); + .insert("_browser".to_owned(), Box::new(make_module)); vm.frozen.borrow_mut().extend(py_compile_bytecode!( file = "src/browser.py", module_name = "browser", diff --git a/wasm/lib/src/js_module.rs b/wasm/lib/src/js_module.rs index f640b1d146..bd7e5250a9 100644 --- a/wasm/lib/src/js_module.rs +++ b/wasm/lib/src/js_module.rs @@ -99,7 +99,7 @@ impl PyJsValue { } else if proto.value.is_null() { Object::create(proto.value.unchecked_ref()) } else { - return Err(vm.new_value_error("prototype must be an Object or null".to_string())); + return Err(vm.new_value_error("prototype must be an Object or null".to_owned())); } } else { Object::new() @@ -140,7 +140,7 @@ impl PyJsValue { let func = self .value .dyn_ref::() - .ok_or_else(|| vm.new_type_error("JS value is not callable".to_string()))?; + .ok_or_else(|| vm.new_type_error("JS value is not callable".to_owned()))?; let this = opts .this .map(|this| this.value.clone()) @@ -164,7 +164,7 @@ impl PyJsValue { let ctor = self .value .dyn_ref::() - .ok_or_else(|| vm.new_type_error("JS value is not callable".to_string()))?; + .ok_or_else(|| vm.new_type_error("JS value is not callable".to_owned()))?; let proto = opts .prototype .as_ref() @@ -256,5 +256,5 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { pub fn setup_js_module(vm: &VirtualMachine) { vm.stdlib_inits .borrow_mut() - .insert("_js".to_string(), Box::new(make_module)); + .insert("_js".to_owned(), Box::new(make_module)); } diff --git a/wasm/lib/src/vm_class.rs b/wasm/lib/src/vm_class.rs index 8565884bd3..b7cf90d2ad 100644 --- a/wasm/lib/src/vm_class.rs +++ b/wasm/lib/src/vm_class.rs @@ -39,7 +39,7 @@ impl StoredVirtualMachine { js_module::setup_js_module(&vm); if inject_browser_module { vm.stdlib_inits.borrow_mut().insert( - "_window".to_string(), + "_window".to_owned(), Box::new(|vm| { py_module!(vm, "_window", { "window" => js_module::PyJsValue::new(wasm_builtins::window()).into_ref(vm), @@ -289,7 +289,7 @@ impl WASMVirtualMachine { |StoredVirtualMachine { ref vm, ref scope, .. }| { - let source_path = source_path.unwrap_or_else(|| "".to_string()); + let source_path = source_path.unwrap_or_else(|| "".to_owned()); let code = vm.compile(source, mode, source_path); let code = code.map_err(|err| { let js_err = SyntaxError::new(&format!("Error parsing Python code: {}", err)); From 7d0d313aa573bada831fa3d8181df3fc34212393 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Wed, 5 Feb 2020 22:03:36 +0900 Subject: [PATCH 12/26] &str::to_string -> &str::to_owned for variables --- compiler/src/compile.rs | 36 +++++++++++----------- compiler/src/symboltable.rs | 6 ++-- derive/src/compile_bytecode.rs | 2 +- derive/src/pyclass.rs | 2 +- parser/src/fstring.rs | 2 +- src/main.rs | 6 ++-- vm/src/builtins.rs | 4 +-- vm/src/dictdatatype.rs | 6 ++-- vm/src/eval.rs | 2 +- vm/src/exceptions.rs | 2 +- vm/src/format.rs | 4 +-- vm/src/frame.rs | 6 ++-- vm/src/import.rs | 2 +- vm/src/obj/objbool.rs | 2 +- vm/src/obj/objbyteinner.rs | 2 +- vm/src/obj/objdict.rs | 2 +- vm/src/obj/objint.rs | 2 +- vm/src/obj/objlist.rs | 2 +- vm/src/obj/objstr.rs | 55 +++++++++++++++++----------------- vm/src/obj/objsuper.rs | 4 +-- vm/src/obj/objtype.rs | 10 +++---- vm/src/py_serde.rs | 2 +- vm/src/stdlib/ast.rs | 32 +++++++++----------- vm/src/stdlib/csv.rs | 4 +-- vm/src/stdlib/dis.rs | 2 +- vm/src/stdlib/hashlib.rs | 2 +- vm/src/stdlib/io.rs | 10 +++---- vm/src/stdlib/itertools.rs | 2 +- vm/src/stdlib/keyword.rs | 2 +- vm/src/stdlib/os.rs | 8 ++--- vm/src/stdlib/re.rs | 2 +- vm/src/stdlib/subprocess.rs | 2 +- vm/src/stdlib/symtable.rs | 4 +-- vm/src/stdlib/zlib.rs | 2 +- vm/src/sysmodule.rs | 12 ++++---- vm/src/version.rs | 8 ++--- vm/src/vm.rs | 4 +-- 37 files changed, 126 insertions(+), 131 deletions(-) diff --git a/compiler/src/compile.rs b/compiler/src/compile.rs index 8ea3bc5207..dbe938fd16 100644 --- a/compiler/src/compile.rs +++ b/compiler/src/compile.rs @@ -290,7 +290,7 @@ impl Compiler { 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 Compiler { 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 Compiler { 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 Compiler { 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 Compiler { compile_varargs(&args.kwarg), self.source_path.clone().unwrap(), line_number, - name.to_string(), + name.to_owned(), )); self.enter_scope(); @@ -909,7 +909,7 @@ impl Compiler { 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,7 +982,7 @@ impl Compiler { Varargs::None, self.source_path.clone().unwrap(), line_number, - name.to_string(), + name.to_owned(), )); self.enter_scope(); @@ -1022,7 +1022,7 @@ impl Compiler { }); self.emit(Instruction::LoadConst { value: bytecode::Constant::String { - value: name.to_string(), + value: name.to_owned(), }, }); @@ -1044,7 +1044,7 @@ impl Compiler { 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! @@ -1308,7 +1308,7 @@ impl Compiler { }); 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 Compiler { 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 Compiler { Attribute { value, name } => { self.compile_expression(value)?; self.emit(Instruction::LoadAttr { - name: name.to_string(), + name: name.to_owned(), }); } Compare { vals, ops } => { @@ -1795,7 +1795,7 @@ impl Compiler { 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 Compiler { 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,7 +1927,7 @@ impl Compiler { ast::ComprehensionKind::Set { .. } => "", ast::ComprehensionKind::Dict { .. } => "", } - .to_string(); + .to_owned(); let line_number = self.get_source_line_number(); // Create magnificent function : @@ -2099,7 +2099,7 @@ impl Compiler { ast::StringGroup::Constant { value } => { self.emit(Instruction::LoadConst { value: bytecode::Constant::String { - value: value.to_string(), + value: value.to_owned(), }, }); } @@ -2266,7 +2266,7 @@ mod tests { let mut compiler: Compiler = Default::default(); compiler.source_path = Some("source_path".to_owned()); compiler.push_new_code_object("".to_owned()); - let ast = parser::parse_program(&source.to_string()).unwrap(); + 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() diff --git a/compiler/src/symboltable.rs b/compiler/src/symboltable.rs index c3e2099bcf..d08aa4f2e3 100644 --- a/compiler/src/symboltable.rs +++ b/compiler/src/symboltable.rs @@ -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: diff --git a/derive/src/compile_bytecode.rs b/derive/src/compile_bytecode.rs index 01f5226d60..1206469fa4 100644 --- a/derive/src/compile_bytecode.rs +++ b/derive/src/compile_bytecode.rs @@ -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) }; diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index fb6ac4b04e..006bd4e60a 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -620,7 +620,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]), diff --git a/parser/src/fstring.rs b/parser/src/fstring.rs index 7ecd8a1239..5ca92c484b 100644 --- a/parser/src/fstring.rs +++ b/parser/src/fstring.rs @@ -83,7 +83,7 @@ impl<'a> FStringParser<'a> { })) } else { spec = Some(Box::new(Constant { - value: spec_expression.to_string(), + value: spec_expression.to_owned(), })) } } diff --git a/src/main.rs b/src/main.rs index 9253e7f65f..4b82077b31 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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") { @@ -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!( diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 3f545a79ef..72891812cf 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -146,7 +146,7 @@ fn builtin_compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult { .parse::() .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)) } @@ -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)? diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index d7dcb8fc34..5541f17583 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -344,7 +344,7 @@ impl DictKey for &PyObjectRef { impl DictKey for &str { fn do_hash(self, _vm: &VirtualMachine) -> PyResult { // 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) } } @@ -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."); diff --git a/vm/src/eval.rs b/vm/src/eval.rs index 3d998f8b40..68255302bd 100644 --- a/vm/src/eval.rs +++ b/vm/src/eval.rs @@ -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) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 208272bb19..135cb0d6f4 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -225,7 +225,7 @@ fn print_source_line(output: &mut W, filename: &str, lineno: usize) -> /// Print exception occurrence location from traceback element fn write_traceback_entry(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 {}"##, diff --git a/vm/src/format.rs b/vm/src/format.rs index 39c6ac2e7b..73d444a8e9 100644 --- a/vm/src/format.rs +++ b/vm/src/format.rs @@ -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() }; @@ -638,7 +638,7 @@ impl FormatString { if let Ok(index) = arg_part.parse::() { 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)) } } diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 82b76b32d4..4466bc881f 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -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) } diff --git a/vm/src/import.rs b/vm/src/import.rs index 866d8c04f1..bcfe4ba228 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -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)?; } diff --git a/vm/src/obj/objbool.rs b/vm/src/obj/objbool.rs index a4b751c7e5..264d305999 100644 --- a/vm/src/obj/objbool.rs +++ b/vm/src/obj/objbool.rs @@ -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()), }); } diff --git a/vm/src/obj/objbyteinner.rs b/vm/src/obj/objbyteinner.rs index 6a21f461fd..a507900e8b 100644 --- a/vm/src/obj/objbyteinner.rs +++ b/vm/src/obj/objbyteinner.rs @@ -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() )), }), }; diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs index d00e404a41..8eca812990 100644 --- a/vm/src/obj/objdict.rs +++ b/vm/src/obj/objdict.rs @@ -524,7 +524,7 @@ 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 { diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index a54833528c..acb2cc70cc 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -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()) ), } } diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs index 5dc58f26cd..94b8548736 100644 --- a/vm/src/obj/objlist.rs +++ b/vm/src/obj/objlist.rs @@ -453,7 +453,7 @@ 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 { diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs index 10e6eba69d..9be0512307 100644 --- a/vm/src/obj/objstr.rs +++ b/vm/src/obj/objstr.rs @@ -61,7 +61,7 @@ impl PyString { impl From<&str> for PyString { fn from(s: &str) -> PyString { - s.to_string().into() + s.to_owned().into() } } @@ -277,7 +277,7 @@ impl PyString { Either::B(slice) => { let string = self .value - .to_string() + .to_owned() .get_slice_items(vm, slice.as_object())?; Ok(vm.new_str(string)) } @@ -419,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) @@ -447,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 @@ -474,31 +474,31 @@ impl PyString { fn strip(&self, chars: OptionalArg, _vm: &VirtualMachine) -> 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, _vm: &VirtualMachine) -> 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, _vm: &VirtualMachine) -> 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] @@ -904,7 +904,7 @@ 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 { @@ -923,7 +923,7 @@ 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())); @@ -985,7 +985,7 @@ impl PyString { fn zfill(&self, len: usize, _vm: &VirtualMachine) -> String { let value = &self.value; if len <= value.len() { - value.to_string() + value.to_owned() } else { format!("{}{}", "0".repeat(len - value.len()), value) } @@ -1017,7 +1017,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 +1033,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 +1051,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; @@ -1264,7 +1264,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 +1314,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()) { @@ -1485,7 +1485,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) @@ -1555,8 +1555,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; @@ -1585,7 +1584,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) diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs index c47c64057c..a9b5aed07e 100644 --- a/vm/src/obj/objsuper.rs +++ b/vm/src/obj/objsuper.rs @@ -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(), )); } } @@ -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()), }); } diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index e7465e6ccf..b4a0169417 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -101,7 +101,7 @@ impl PyClassRef { let attributes = self.get_attributes(); let attributes: Vec = attributes .keys() - .map(|k| vm.ctx.new_str(k.to_string())) + .map(|k| vm.ctx.new_str(k.to_owned())) .collect(); PyList::from(attributes) } @@ -220,7 +220,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,7 +228,7 @@ impl PyClassRef { pub fn set_str_attr>(&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)] @@ -448,7 +448,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 +548,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) diff --git a/vm/src/py_serde.rs b/vm/src/py_serde.rs index 3bd8bedbf4..47520bb130 100644 --- a/vm/src/py_serde.rs +++ b/vm/src/py_serde.rs @@ -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(self, value: String) -> Result diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index d25429dcb3..33b3ea6226 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -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 { 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 { @@ -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) -> PyObjectRef { if let Some(name) = name { - vm.ctx.new_str(name.to_string()) + vm.ctx.new_str(name.to_owned()) } else { vm.ctx.none() } diff --git a/vm/src/stdlib/csv.rs b/vm/src/stdlib/csv.rs index 5ed4d71ff5..fc42643a2a 100644 --- a/vm/src/stdlib/csv.rs +++ b/vm/src/stdlib/csv.rs @@ -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 { diff --git a/vm/src/stdlib/dis.rs b/vm/src/stdlib/dis.rs index a3f0359855..adc31ff17e 100644 --- a/vm/src/stdlib/dis.rs +++ b/vm/src/stdlib/dis.rs @@ -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(); diff --git a/vm/src/stdlib/hashlib.rs b/vm/src/stdlib/hashlib.rs index 4b8f6b4122..98a7ce9dd9 100644 --- a/vm/src/stdlib/hashlib.rs +++ b/vm/src/stdlib/hashlib.rs @@ -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), } } diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index ee4ec13d45..378fe5f4f1 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -770,7 +770,7 @@ fn text_io_wrapper_write( 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) @@ -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(); @@ -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() ) ); } diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index 79253a36d9..e0a104041d 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -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 { diff --git a/vm/src/stdlib/keyword.rs b/vm/src/stdlib/keyword.rs index cede07e880..e22590ab4a 100644 --- a/vm/src/stdlib/keyword.rs +++ b/vm/src/stdlib/keyword.rs @@ -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(), ); diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index a5b35ecacd..a6be3e5262 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -312,7 +312,7 @@ fn os_access(path: PyStringRef, mode: u8, vm: &VirtualMachine) -> PyResult 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 } fn os_error(message: OptionalArg, vm: &VirtualMachine) -> PyResult { - let msg = message.map_or("".to_owned(), |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)) } @@ -524,7 +524,7 @@ impl DirEntryRef { } fn path(self, _vm: &VirtualMachine) -> String { - self.entry.path().to_str().unwrap().to_string() + self.entry.path().to_str().unwrap().to_owned() } #[allow(clippy::match_bool)] @@ -877,7 +877,7 @@ fn os_getcwd(vm: &VirtualMachine) -> PyResult { .as_path() .to_str() .unwrap() - .to_string()) + .to_owned()) } fn os_chdir(path: PyStringRef, vm: &VirtualMachine) -> PyResult<()> { diff --git a/vm/src/stdlib/re.rs b/vm/src/stdlib/re.rs index 9de904e414..25203ba1c2 100644 --- a/vm/src/stdlib/re.rs +++ b/vm/src/stdlib/re.rs @@ -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(), }) } diff --git a/vm/src/stdlib/subprocess.rs b/vm/src/stdlib/subprocess.rs index 57ddfc780b..78e8bfafc5 100644 --- a/vm/src/stdlib/subprocess.rs +++ b/vm/src/stdlib/subprocess.rs @@ -106,7 +106,7 @@ impl PopenRef { let stdout = convert_redirection(args.stdout, vm)?; let stderr = convert_redirection(args.stderr, vm)?; let command_list = match &args.args { - Either::A(command) => vec![command.as_str().to_string()], + Either::A(command) => vec![command.as_str().to_owned()], Either::B(command_list) => command_list .borrow_elements() .iter() diff --git a/vm/src/stdlib/symtable.rs b/vm/src/stdlib/symtable.rs index 0591b87496..d32afd44a2 100644 --- a/vm/src/stdlib/symtable.rs +++ b/vm/src/stdlib/symtable.rs @@ -110,7 +110,7 @@ impl PySymbolTable { } .into_ref(vm)) } else { - Err(vm.new_lookup_error(name.to_string())) + Err(vm.new_lookup_error(name.to_owned())) } } @@ -120,7 +120,7 @@ impl PySymbolTable { .symtable .symbols .keys() - .map(|s| vm.ctx.new_str(s.to_string())) + .map(|s| vm.ctx.new_str(s.to_owned())) .collect(); Ok(vm.ctx.new_list(symbols)) } diff --git a/vm/src/stdlib/zlib.rs b/vm/src/stdlib/zlib.rs index cebef22adf..b1b44b2bcb 100644 --- a/vm/src/stdlib/zlib.rs +++ b/vm/src/stdlib/zlib.rs @@ -121,5 +121,5 @@ fn zlib_error(message: &str, vm: &VirtualMachine) -> PyBaseExceptionRef { let zlib_error = vm.get_attribute(module, "error").unwrap(); let zlib_error = zlib_error.downcast().unwrap(); - vm.new_exception_msg(zlib_error, message.to_string()) + vm.new_exception_msg(zlib_error, message.to_owned()) } diff --git a/vm/src/sysmodule.rs b/vm/src/sysmodule.rs index 072fa59b88..fdb04de47e 100644 --- a/vm/src/sysmodule.rs +++ b/vm/src/sysmodule.rs @@ -345,7 +345,7 @@ settrace() -- set the global debug tracing function "argv" => argv(vm), "builtin_module_names" => builtin_module_names, "byteorder" => ctx.new_str(bytorder), - "copyright" => ctx.new_str(copyright.to_string()), + "copyright" => ctx.new_str(copyright.to_owned()), "executable" => executable(ctx), "flags" => flags, "getrefcount" => ctx.new_function(sys_getrefcount), @@ -363,7 +363,7 @@ settrace() -- set the global debug tracing function "path" => path, "ps1" => ctx.new_str(">>>>> ".to_owned()), "ps2" => ctx.new_str("..... ".to_owned()), - "__doc__" => ctx.new_str(sys_doc.to_string()), + "__doc__" => ctx.new_str(sys_doc.to_owned()), "_getframe" => ctx.new_function(getframe), "modules" => modules.clone(), "warnoptions" => ctx.new_list(vec![]), @@ -381,10 +381,10 @@ settrace() -- set the global debug tracing function "version_info" => version_info, "_git" => sys_git_info(vm), "exc_info" => ctx.new_function(sys_exc_info), - "prefix" => ctx.new_str(prefix.to_string()), - "base_prefix" => ctx.new_str(base_prefix.to_string()), - "exec_prefix" => ctx.new_str(exec_prefix.to_string()), - "base_exec_prefix" => ctx.new_str(base_exec_prefix.to_string()), + "prefix" => ctx.new_str(prefix.to_owned()), + "base_prefix" => ctx.new_str(base_prefix.to_owned()), + "exec_prefix" => ctx.new_str(exec_prefix.to_owned()), + "base_exec_prefix" => ctx.new_str(base_exec_prefix.to_owned()), "exit" => ctx.new_function(sys_exit), "abiflags" => ctx.new_str("".to_owned()), }); diff --git a/vm/src/version.rs b/vm/src/version.rs index c14f6c2943..5981d17c57 100644 --- a/vm/src/version.rs +++ b/vm/src/version.rs @@ -71,17 +71,17 @@ pub fn get_build_info() -> String { } pub fn get_git_revision() -> String { - option_env!("RUSTPYTHON_GIT_HASH").unwrap_or("").to_string() + option_env!("RUSTPYTHON_GIT_HASH").unwrap_or("").to_owned() } pub fn get_git_tag() -> String { - option_env!("RUSTPYTHON_GIT_TAG").unwrap_or("").to_string() + option_env!("RUSTPYTHON_GIT_TAG").unwrap_or("").to_owned() } pub fn get_git_branch() -> String { option_env!("RUSTPYTHON_GIT_BRANCH") .unwrap_or("") - .to_string() + .to_owned() } pub fn get_git_identifier() -> String { @@ -98,7 +98,7 @@ pub fn get_git_identifier() -> String { fn get_git_timestamp_datetime() -> DateTime { let timestamp = option_env!("RUSTPYTHON_GIT_TIMESTAMP") .unwrap_or("") - .to_string(); + .to_owned(); let timestamp = timestamp.parse::().unwrap_or(0); let datetime = UNIX_EPOCH + Duration::from_secs(timestamp); diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 7ea7215fbc..8d573327da 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -576,7 +576,7 @@ impl VirtualMachine { let from_list = self.ctx.new_tuple( from_list .iter() - .map(|name| self.new_str(name.to_string())) + .map(|name| self.new_str(name.to_owned())) .collect(), ); self.invoke( @@ -908,7 +908,7 @@ impl VirtualMachine { compile::compile(source, mode, source_path, self.settings.optimize) .map(|codeobj| PyCode::new(codeobj).into_ref(self)) .map_err(|mut compile_error| { - compile_error.update_statement_info(source.trim_end().to_string()); + compile_error.update_statement_info(source.trim_end().to_owned()); compile_error }) } From 9f5cd17f2bc296ddf97c4e8311000234f8222d43 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sun, 2 Feb 2020 21:43:24 +0900 Subject: [PATCH 13/26] Add getset_descriptor --- vm/src/obj/mod.rs | 1 + vm/src/obj/objgetset.rs | 71 +++++++++++++++++++++++++++++++++++++++++ vm/src/obj/objobject.rs | 4 +-- vm/src/pyobject.rs | 4 +++ vm/src/types.rs | 5 +++ 5 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 vm/src/obj/objgetset.rs diff --git a/vm/src/obj/mod.rs b/vm/src/obj/mod.rs index 57233025da..af5d531d1d 100644 --- a/vm/src/obj/mod.rs +++ b/vm/src/obj/mod.rs @@ -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; diff --git a/vm/src/obj/objgetset.rs b/vm/src/obj/objgetset.rs new file mode 100644 index 0000000000..e8ee40b67d --- /dev/null +++ b/vm/src/obj/objgetset.rs @@ -0,0 +1,71 @@ +/*! Python `attribute` descriptor class. (PyGetSet) + +*/ +use super::objtype::PyClassRef; +use crate::function::OptionalArg; +use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue}; +use crate::slots::PyBuiltinDescriptor; +use crate::vm::VirtualMachine; + +pub type PyGetter = dyn Fn(PyObjectRef, &VirtualMachine) -> PyResult; +pub type PySetter = dyn Fn(PyObjectRef, PyObjectRef, &VirtualMachine) -> PyResult<()>; + +#[pyclass] +pub struct PyGetSet { + // name: String, + getter: Box, + setter: Box, + // doc: Option, +} + +impl std::fmt::Debug for PyGetSet { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "PyGetSet {{ getter: {:p}, setter: {:p} }}", + self.getter, self.setter + ) + } +} + +impl PyValue for PyGetSet { + fn class(vm: &VirtualMachine) -> PyClassRef { + vm.ctx.getset_type() + } +} + +pub type PyGetSetRef = PyRef; + +impl PyBuiltinDescriptor for PyGetSet { + fn get( + zelf: PyRef, + obj: PyObjectRef, + _cls: OptionalArg, + vm: &VirtualMachine, + ) -> PyResult { + (zelf.getter)(obj, vm) + } +} + +impl PyGetSet { + pub fn new(getter: &'static PyGetter, setter: &'static PySetter) -> Self { + Self { + getter: Box::new(getter), + setter: Box::new(setter), + } + } +} + +#[pyimpl(with(PyBuiltinDescriptor))] +impl PyGetSet { + // Descriptor methods + + #[pymethod(magic)] + fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { + (self.setter)(obj, value, vm) + } +} + +pub(crate) fn init(context: &PyContext) { + PyGetSet::extend_class(context, &context.types.getset_type); +} diff --git a/vm/src/obj/objobject.rs b/vm/src/obj/objobject.rs index 671dcd9e68..bafec4abbe 100644 --- a/vm/src/obj/objobject.rs +++ b/vm/src/obj/objobject.rs @@ -175,12 +175,12 @@ impl PyBaseObject { } #[pyproperty(name = "__class__")] - fn _class(obj: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef { + fn get_class(obj: PyObjectRef, _vm: &VirtualMachine) -> 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))) } diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index db0df14a11..555d480bd4 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -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() } diff --git a/vm/src/types.rs b/vm/src/types.rs index 2c9d940265..a81755a010 100644 --- a/vm/src/types.rs +++ b/vm/src/types.rs @@ -14,6 +14,7 @@ use crate::obj::objfloat; use crate::obj::objframe; use crate::obj::objfunction; use crate::obj::objgenerator; +use crate::obj::objgetset; use crate::obj::objint; use crate::obj::objiter; use crate::obj::objlist; @@ -94,6 +95,7 @@ pub struct TypeZoo { pub method_descriptor_type: PyClassRef, pub property_type: PyClassRef, pub readonly_property_type: PyClassRef, + pub getset_type: PyClassRef, pub module_type: PyClassRef, pub namespace_type: PyClassRef, pub bound_method_type: PyClassRef, @@ -125,6 +127,7 @@ impl TypeZoo { let method_descriptor_type = create_type("method_descriptor", &type_type, &object_type); let property_type = create_type("property", &type_type, &object_type); let readonly_property_type = create_type("readonly_property", &type_type, &object_type); + let getset_type = create_type("getset_descriptor", &type_type, &object_type); let super_type = create_type("super", &type_type, &object_type); let weakref_type = create_type("ref", &type_type, &object_type); let weakproxy_type = create_type("weakproxy", &type_type, &object_type); @@ -220,6 +223,7 @@ impl TypeZoo { mappingproxy_type, property_type, readonly_property_type, + getset_type, generator_type, module_type, namespace_type, @@ -381,6 +385,7 @@ pub fn initialize_types(context: &PyContext) { objbytes::init(&context); objbytearray::init(&context); objproperty::init(&context); + objgetset::init(&context); objmemory::init(&context); objstr::init(&context); objrange::init(&context); From c3d5f6c14598be14bee72d2f1ec5405566d6e735 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sun, 2 Feb 2020 22:56:28 +0900 Subject: [PATCH 14/26] IntoPyGetterFunc, IntoPySetterFunc --- derive/src/pyclass.rs | 7 ++- vm/src/obj/objgetset.rs | 107 +++++++++++++++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 17 deletions(-) diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 006bd4e60a..5265bdd739 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -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; diff --git a/vm/src/obj/objgetset.rs b/vm/src/obj/objgetset.rs index e8ee40b67d..ce3e73a13e 100644 --- a/vm/src/obj/objgetset.rs +++ b/vm/src/obj/objgetset.rs @@ -3,18 +3,57 @@ */ use super::objtype::PyClassRef; use crate::function::OptionalArg; -use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue}; +use crate::pyobject::{ + IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, +}; use crate::slots::PyBuiltinDescriptor; use crate::vm::VirtualMachine; -pub type PyGetter = dyn Fn(PyObjectRef, &VirtualMachine) -> PyResult; -pub type PySetter = dyn Fn(PyObjectRef, PyObjectRef, &VirtualMachine) -> PyResult<()>; +pub type PyGetterFunc = Box PyResult>; +pub type PySetterFunc = Box PyResult<()>>; + +pub trait IntoPyGetterFunc { + fn into_getter(self) -> PyGetterFunc; +} + +impl IntoPyGetterFunc 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) + }) + } +} + +pub trait IntoPySetterFunc { + fn into_setter(self) -> PySetterFunc; +} + +impl IntoPySetterFunc for F +where + F: Fn(T, V, &VirtualMachine) -> PyResult<()> + 'static, + T: TryFromObject, + V: TryFromObject, +{ + 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) + }) + } +} #[pyclass] pub struct PyGetSet { - // name: String, - getter: Box, - setter: Box, + name: String, + getter: Option, + setter: Option, // doc: Option, } @@ -22,8 +61,18 @@ impl std::fmt::Debug for PyGetSet { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, - "PyGetSet {{ getter: {:p}, setter: {:p} }}", - self.getter, self.setter + "PyGetSet {{ name: {}, getter: {}, setter: {} }}", + self.name, + if self.getter.is_some() { + "Some" + } else { + "None" + }, + if self.setter.is_some() { + "Some" + } else { + "None" + }, ) } } @@ -43,15 +92,39 @@ impl PyBuiltinDescriptor for PyGetSet { _cls: OptionalArg, vm: &VirtualMachine, ) -> PyResult { - (zelf.getter)(obj, vm) + 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 new(getter: &'static PyGetter, setter: &'static PySetter) -> Self { + pub fn with_get(name: String, getter: G) -> Self + where + G: IntoPyGetterFunc, + { + Self { + name, + getter: Some(getter.into_getter()), + setter: None, + } + } + + pub fn with_get_set(name: String, getter: G, setter: S) -> Self + where + G: IntoPyGetterFunc, + S: IntoPySetterFunc, + { Self { - getter: Box::new(getter), - setter: Box::new(setter), + name, + getter: Some(getter.into_getter()), + setter: Some(setter.into_setter()), } } } @@ -62,7 +135,15 @@ impl PyGetSet { #[pymethod(magic)] fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - (self.setter)(obj, value, vm) + 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 + ))) + } } } From ca557788c8d9330079cfadd05798feeeb5fe57f0 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 4 Feb 2020 02:00:57 +0900 Subject: [PATCH 15/26] `&self` support for getter/setter --- vm/src/obj/objgetset.rs | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/vm/src/obj/objgetset.rs b/vm/src/obj/objgetset.rs index ce3e73a13e..c3c8d12f36 100644 --- a/vm/src/obj/objgetset.rs +++ b/vm/src/obj/objgetset.rs @@ -2,7 +2,7 @@ */ use super::objtype::PyClassRef; -use crate::function::OptionalArg; +use crate::function::{OptionalArg, OwnedParam, RefParam}; use crate::pyobject::{ IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, }; @@ -16,7 +16,7 @@ pub trait IntoPyGetterFunc { fn into_getter(self) -> PyGetterFunc; } -impl IntoPyGetterFunc for F +impl IntoPyGetterFunc, R> for F where F: Fn(T, &VirtualMachine) -> R + 'static, T: TryFromObject, @@ -30,11 +30,25 @@ where } } +impl IntoPyGetterFunc, R> 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::::try_from_object(vm, obj)?; + (self)(&zelf, vm).into_pyobject(vm) + }) + } +} + pub trait IntoPySetterFunc { fn into_setter(self) -> PySetterFunc; } -impl IntoPySetterFunc for F +impl IntoPySetterFunc, V> for F where F: Fn(T, V, &VirtualMachine) -> PyResult<()> + 'static, T: TryFromObject, @@ -49,6 +63,21 @@ where } } +impl IntoPySetterFunc, V> for F +where + F: Fn(&S, V, &VirtualMachine) -> PyResult<()> + 'static, + S: PyValue, + V: TryFromObject, +{ + fn into_setter(self) -> PySetterFunc { + Box::new(move |vm, obj, value| { + let zelf = PyRef::::try_from_object(vm, obj)?; + let value = V::try_from_object(vm, value)?; + (self)(&zelf, value, vm) + }) + } +} + #[pyclass] pub struct PyGetSet { name: String, From d1f9cb4e58762d8084f812b4936f180b0a3ebbe4 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 4 Feb 2020 03:17:42 +0900 Subject: [PATCH 16/26] PySetResult and IntoPySetResult --- vm/src/obj/objgetset.rs | 40 ++++++++++++++++++++++++++++++--------- vm/src/obj/objproperty.rs | 12 ++++++------ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/vm/src/obj/objgetset.rs b/vm/src/obj/objgetset.rs index c3c8d12f36..1e257f1891 100644 --- a/vm/src/obj/objgetset.rs +++ b/vm/src/obj/objgetset.rs @@ -44,36 +44,57 @@ where } } -pub trait IntoPySetterFunc { +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 +where + R: IntoPyNoResult, +{ fn into_setter(self) -> PySetterFunc; } -impl IntoPySetterFunc, V> for F +impl IntoPySetterFunc, V, R> for F where - F: Fn(T, V, &VirtualMachine) -> PyResult<()> + 'static, + 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) + (self)(obj, value, vm).into_noresult() }) } } -impl IntoPySetterFunc, V> for F +impl IntoPySetterFunc, V, R> for F where - F: Fn(&S, V, &VirtualMachine) -> PyResult<()> + 'static, + 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::::try_from_object(vm, obj)?; let value = V::try_from_object(vm, value)?; - (self)(&zelf, value, vm) + (self)(&zelf, value, vm).into_noresult() }) } } @@ -145,10 +166,11 @@ impl PyGetSet { } } - pub fn with_get_set(name: String, getter: G, setter: S) -> Self + pub fn with_get_set(name: String, getter: G, setter: S) -> Self where G: IntoPyGetterFunc, - S: IntoPySetterFunc, + S: IntoPySetterFunc, + SR: IntoPyNoResult, { Self { name, diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index d25feb227c..52645e185f 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -259,11 +259,6 @@ pub struct PropertyBuilder<'a> { setter: Option, } -pub trait PropertySetterResult {} - -impl PropertySetterResult for PyResult<()> {} -impl PropertySetterResult for () {} - impl<'a> PropertyBuilder<'a> { pub fn new(ctx: &'a PyContext) -> Self { Self { @@ -282,7 +277,12 @@ impl<'a> PropertyBuilder<'a> { } } - pub fn add_setter>( + pub fn add_setter< + I, + V, + VM, + F: IntoPyNativeFunc<(I, V), impl super::objgetset::IntoPyNoResult, VM>, + >( self, func: F, ) -> Self { From 226a2a6cb9f5f71206430a2ef7f5b39135ba6e9f Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 4 Feb 2020 04:21:32 +0900 Subject: [PATCH 17/26] VM polymorphism for getter and setter --- vm/src/obj/objgetset.rs | 72 +++++++++++++++++++++++++++++++-------- vm/src/obj/objproperty.rs | 2 +- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/vm/src/obj/objgetset.rs b/vm/src/obj/objgetset.rs index 1e257f1891..13dadd536d 100644 --- a/vm/src/obj/objgetset.rs +++ b/vm/src/obj/objgetset.rs @@ -12,11 +12,11 @@ use crate::vm::VirtualMachine; pub type PyGetterFunc = Box PyResult>; pub type PySetterFunc = Box PyResult<()>>; -pub trait IntoPyGetterFunc { +pub trait IntoPyGetterFunc { fn into_getter(self) -> PyGetterFunc; } -impl IntoPyGetterFunc, R> for F +impl IntoPyGetterFunc<(OwnedParam, R, VirtualMachine)> for F where F: Fn(T, &VirtualMachine) -> R + 'static, T: TryFromObject, @@ -30,7 +30,7 @@ where } } -impl IntoPyGetterFunc, R> for F +impl IntoPyGetterFunc<(RefParam, R, VirtualMachine)> for F where F: Fn(&S, &VirtualMachine) -> R + 'static, S: PyValue, @@ -44,6 +44,28 @@ where } } +impl IntoPyGetterFunc<(OwnedParam, 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 IntoPyGetterFunc<(RefParam, 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<()>; } @@ -60,14 +82,11 @@ impl IntoPyNoResult for PyResult<()> { } } -pub trait IntoPySetterFunc -where - R: IntoPyNoResult, -{ +pub trait IntoPySetterFunc { fn into_setter(self) -> PySetterFunc; } -impl IntoPySetterFunc, V, R> for F +impl IntoPySetterFunc<(OwnedParam, V, R, VirtualMachine)> for F where F: Fn(T, V, &VirtualMachine) -> R + 'static, T: TryFromObject, @@ -83,7 +102,7 @@ where } } -impl IntoPySetterFunc, V, R> for F +impl IntoPySetterFunc<(RefParam, V, R, VirtualMachine)> for F where F: Fn(&S, V, &VirtualMachine) -> R + 'static, S: PyValue, @@ -99,6 +118,30 @@ where } } +impl IntoPySetterFunc<(OwnedParam, 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 IntoPySetterFunc<(RefParam, 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, @@ -155,9 +198,9 @@ impl PyBuiltinDescriptor for PyGetSet { } impl PyGetSet { - pub fn with_get(name: String, getter: G) -> Self + pub fn with_get(name: String, getter: G) -> Self where - G: IntoPyGetterFunc, + G: IntoPyGetterFunc, { Self { name, @@ -166,11 +209,10 @@ impl PyGetSet { } } - pub fn with_get_set(name: String, getter: G, setter: S) -> Self + pub fn with_get_set(name: String, getter: G, setter: S) -> Self where - G: IntoPyGetterFunc, - S: IntoPySetterFunc, - SR: IntoPyNoResult, + G: IntoPyGetterFunc, + S: IntoPySetterFunc, { Self { name, diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index 52645e185f..8dd3ce0a6f 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -268,7 +268,7 @@ impl<'a> PropertyBuilder<'a> { } } - pub fn add_getter>(self, func: F) -> Self { + pub fn add_getter>(self, func: F) -> Self { let func = self.ctx.new_method(func); Self { ctx: self.ctx, From 23381b9937e6ce241eb17d7ce056483562293340 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Wed, 5 Feb 2020 03:39:19 +0900 Subject: [PATCH 18/26] compatiibility for CPytthon descr_check --- derive/src/pyclass.rs | 7 +++- tests/snippets/types_snippet.py | 4 ++ vm/src/obj/objbuiltinfunc.rs | 26 +++++++------ vm/src/obj/objclassmethod.rs | 15 ++++---- vm/src/obj/objfunction.rs | 19 +++++----- vm/src/obj/objgetset.rs | 18 +++++---- vm/src/obj/objproperty.rs | 28 +++++++------- vm/src/obj/objstaticmethod.rs | 15 ++++---- vm/src/obj/objtype.rs | 8 +++- vm/src/obj/objweakref.rs | 6 +-- vm/src/slots.rs | 65 +++++++++++++++++++++++++++++---- vm/src/vm.rs | 9 ++++- 12 files changed, 151 insertions(+), 69 deletions(-) diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 5265bdd739..7a75785a86 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -452,8 +452,13 @@ fn extract_impl_items(mut items: Vec) -> Result { + 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); diff --git a/tests/snippets/types_snippet.py b/tests/snippets/types_snippet.py index 230c2eba29..81ee9ef732 100644 --- a/tests/snippets/types_snippet.py +++ b/tests/snippets/types_snippet.py @@ -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 diff --git a/vm/src/obj/objbuiltinfunc.rs b/vm/src/obj/objbuiltinfunc.rs index 124eb4099a..767e6294ec 100644 --- a/vm/src/obj/objbuiltinfunc.rs +++ b/vm/src/obj/objbuiltinfunc.rs @@ -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, - obj: PyObjectRef, - cls: OptionalArg, +impl SlotDescriptor for PyBuiltinMethod { + fn descr_get( vm: &VirtualMachine, + zelf: PyObjectRef, + obj: Option, + cls: OptionalArg, ) -> 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) { diff --git a/vm/src/obj/objclassmethod.rs b/vm/src/obj/objclassmethod.rs index 05505b9c79..8c3d5070d2 100644 --- a/vm/src/obj/objclassmethod.rs +++ b/vm/src/obj/objclassmethod.rs @@ -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, - obj: PyObjectRef, - cls: OptionalArg, +impl SlotDescriptor for PyClassMethod { + fn descr_get( vm: &VirtualMachine, + zelf: PyObjectRef, + obj: Option, + cls: OptionalArg, ) -> 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( diff --git a/vm/src/obj/objfunction.rs b/vm/src/obj/objfunction.rs index f3b0e1fdb3..24371e85cb 100644 --- a/vm/src/obj/objfunction.rs +++ b/vm/src/obj/objfunction.rs @@ -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; @@ -27,13 +27,14 @@ pub struct PyFunction { kw_only_defaults: Option, } -impl PyBuiltinDescriptor for PyFunction { - fn get( - zelf: PyRef, - obj: PyObjectRef, - cls: OptionalArg, +impl SlotDescriptor for PyFunction { + fn descr_get( vm: &VirtualMachine, + zelf: PyObjectRef, + obj: Option, + cls: OptionalArg, ) -> 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)] @@ -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 { diff --git a/vm/src/obj/objgetset.rs b/vm/src/obj/objgetset.rs index 13dadd536d..20e89e09f4 100644 --- a/vm/src/obj/objgetset.rs +++ b/vm/src/obj/objgetset.rs @@ -6,7 +6,7 @@ use crate::function::{OptionalArg, OwnedParam, RefParam}; use crate::pyobject::{ IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, }; -use crate::slots::PyBuiltinDescriptor; +use crate::slots::SlotDescriptor; use crate::vm::VirtualMachine; pub type PyGetterFunc = Box PyResult>; @@ -178,13 +178,17 @@ impl PyValue for PyGetSet { pub type PyGetSetRef = PyRef; -impl PyBuiltinDescriptor for PyGetSet { - fn get( - zelf: PyRef, - obj: PyObjectRef, - _cls: OptionalArg, +impl SlotDescriptor for PyGetSet { + fn descr_get( vm: &VirtualMachine, + zelf: PyObjectRef, + obj: Option, + _cls: OptionalArg, ) -> 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 { @@ -222,7 +226,7 @@ impl PyGetSet { } } -#[pyimpl(with(PyBuiltinDescriptor))] +#[pyimpl(with(SlotDescriptor))] impl PyGetSet { // Descriptor methods diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index 8dd3ce0a6f..cc945f96bd 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -9,7 +9,7 @@ use crate::pyobject::{ IdProtocol, PyClassImpl, PyContext, PyObject, 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__ @@ -27,13 +27,14 @@ impl PyValue for PyReadOnlyProperty { pub type PyReadOnlyPropertyRef = PyRef; -impl PyBuiltinDescriptor for PyReadOnlyProperty { - fn get( - zelf: PyRef, - obj: PyObjectRef, - cls: OptionalArg, +impl SlotDescriptor for PyReadOnlyProperty { + fn descr_get( vm: &VirtualMachine, + zelf: PyObjectRef, + obj: Option, + cls: OptionalArg, ) -> PyResult { + let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?; if vm.is_none(&obj) { if Self::_cls_is(&cls, &vm.ctx.types.type_type) { vm.invoke(&zelf.getter, cls.unwrap()) @@ -46,7 +47,7 @@ impl PyBuiltinDescriptor for PyReadOnlyProperty { } } -#[pyimpl(with(PyBuiltinDescriptor))] +#[pyimpl(with(SlotDescriptor))] impl PyReadOnlyProperty {} /// Property attribute. @@ -110,13 +111,14 @@ struct PropertyArgs { doc: Option, } -impl PyBuiltinDescriptor for PyProperty { - fn get( - zelf: PyRef, - obj: PyObjectRef, - _cls: OptionalArg, +impl SlotDescriptor for PyProperty { + fn descr_get( vm: &VirtualMachine, + zelf: PyObjectRef, + obj: Option, + _cls: OptionalArg, ) -> PyResult { + let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?; if let Some(getter) = zelf.getter.as_ref() { if obj.is(vm.ctx.none.as_object()) { Ok(zelf.into_object()) @@ -129,7 +131,7 @@ impl PyBuiltinDescriptor for PyProperty { } } -#[pyimpl(with(PyBuiltinDescriptor), flags(BASETYPE))] +#[pyimpl(with(SlotDescriptor), flags(BASETYPE))] impl PyProperty { #[pyslot] fn tp_new(cls: PyClassRef, args: PropertyArgs, vm: &VirtualMachine) -> PyResult { diff --git a/vm/src/obj/objstaticmethod.rs b/vm/src/obj/objstaticmethod.rs index eaaf86159d..fbf451064d 100644 --- a/vm/src/obj/objstaticmethod.rs +++ b/vm/src/obj/objstaticmethod.rs @@ -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, - _obj: PyObjectRef, +impl SlotDescriptor for PyStaticMethod { + fn descr_get( + vm: &VirtualMachine, + zelf: PyObjectRef, + _obj: Option, _cls: OptionalArg, - _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( diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index b4a0169417..5ca39913fc 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -9,7 +9,7 @@ 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, @@ -170,7 +170,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()]); } } diff --git a/vm/src/obj/objweakref.rs b/vm/src/obj/objweakref.rs index 436a4a5135..c74bcdfe02 100644 --- a/vm/src/obj/objweakref.rs +++ b/vm/src/obj/objweakref.rs @@ -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; -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] diff --git a/vm/src/slots.rs b/vm/src/slots.rs index 818a1b974b..b673a5d5ed 100644 --- a/vm/src/slots.rs +++ b/vm/src/slots.rs @@ -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, pub call: Option, - pub descr_get: Option, + pub descr_get: Option, } 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, OptionalArg) -> PyResult, +>; + #[pyimpl] -pub trait PyBuiltinDescriptor: PyValue { +pub trait SlotDescriptor: PyValue { + #[pyslot] + fn descr_get( + vm: &VirtualMachine, + zelf: PyObjectRef, + obj: Option, + cls: OptionalArg, + ) -> PyResult; + #[pymethod(magic)] - #[pyslot(descr_get)] fn get( - zelf: PyRef, + zelf: PyObjectRef, obj: PyObjectRef, cls: OptionalArg, vm: &VirtualMachine, - ) -> PyResult; + ) -> PyResult { + Self::descr_get(vm, zelf, Some(obj), cls) + } + + fn _zelf(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult> { + PyRef::::try_from_object(vm, zelf) + } + + fn _unwrap( + zelf: PyObjectRef, + obj: Option, + vm: &VirtualMachine, + ) -> PyResult<(PyRef, 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, + vm: &VirtualMachine, + ) -> Result<(PyRef, 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(cls: &OptionalArg, other: &T) -> bool where diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 8d573327da..ca6cce10da 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -24,7 +24,7 @@ use crate::bytecode; use crate::exceptions::{PyBaseException, PyBaseExceptionRef}; use crate::frame::{ExecutionResult, Frame, FrameRef}; use crate::frozen; -use crate::function::PyFuncArgs; +use crate::function::{OptionalArg, PyFuncArgs}; use crate::import; use crate::obj::objbool; use crate::obj::objcode::{PyCode, PyCodeRef}; @@ -623,7 +623,12 @@ impl VirtualMachine { let slots = attr_class.slots.borrow(); if let Some(descr_get) = slots.borrow().descr_get.as_ref() { let cls = obj.class(); - descr_get(self, vec![attr, obj.clone(), cls.into_object()].into()) + descr_get( + self, + attr, + Some(obj.clone()), + OptionalArg::Present(cls.into_object()), + ) } else if let Some(ref descriptor) = attr_class.get_attr("__get__") { let cls = obj.class(); self.invoke(descriptor, vec![attr, obj.clone(), cls.into_object()]) From 0aee78de18b3286b522fcc8d4d2d5f6301d98d93 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 4 Feb 2020 04:45:04 +0900 Subject: [PATCH 19/26] pyproperty generates PyGetSet instead of PyProperty --- derive/src/pyclass.rs | 17 ++++++++++------- vm/src/exceptions.rs | 16 +++++++++++++--- vm/src/obj/objfloat.rs | 4 ++-- vm/src/obj/objfunction.rs | 6 +++--- vm/src/obj/objint.rs | 1 + vm/src/obj/objtype.rs | 7 +++++++ 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 7a75785a86..b7bdff2c2d 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -405,8 +405,8 @@ fn extract_impl_items(mut items: Vec) -> Result getter, + let getter_func = match prop.0 { + Some(func) => func, None => { push_err_span!( diagnostics, @@ -417,14 +417,17 @@ fn extract_impl_items(mut items: Vec) -> Result (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) ); } }) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 135cb0d6f4..d30a2ed230 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -80,7 +80,7 @@ impl PyBaseException { } #[pyproperty(name = "__traceback__")] - fn get_traceback(&self, _vm: &VirtualMachine) -> Option { + fn get_traceback(&self) -> Option { self.traceback.borrow().clone() } @@ -95,8 +95,13 @@ impl PyBaseException { } #[pyproperty(name = "__cause__", setter)] - fn setter_cause(&self, cause: Option, _vm: &VirtualMachine) { + fn setter_cause( + &self, + cause: Option, + _vm: &VirtualMachine, + ) -> PyResult<()> { self.cause.replace(cause); + Ok(()) } #[pyproperty(name = "__context__")] @@ -105,8 +110,13 @@ impl PyBaseException { } #[pyproperty(name = "__context__", setter)] - fn setter_context(&self, context: Option, _vm: &VirtualMachine) { + fn setter_context( + &self, + context: Option, + _vm: &VirtualMachine, + ) -> PyResult<()> { self.context.replace(context); + Ok(()) } #[pyproperty(name = "__suppress_context__")] diff --git a/vm/src/obj/objfloat.rs b/vm/src/obj/objfloat.rs index 2b660994b0..ffc8e946b6 100644 --- a/vm/src/obj/objfloat.rs +++ b/vm/src/obj/objfloat.rs @@ -498,12 +498,12 @@ impl PyFloat { pyhash::hash_float(self.value) } - #[pyproperty(name = "real")] + #[pyproperty] fn real(zelf: PyRef, _vm: &VirtualMachine) -> PyFloatRef { zelf } - #[pyproperty(name = "imag")] + #[pyproperty] fn imag(&self, _vm: &VirtualMachine) -> f64 { 0.0f64 } diff --git a/vm/src/obj/objfunction.rs b/vm/src/obj/objfunction.rs index 24371e85cb..d3532d01ab 100644 --- a/vm/src/obj/objfunction.rs +++ b/vm/src/obj/objfunction.rs @@ -249,17 +249,17 @@ impl PyFunction { self.invoke(args, vm) } - #[pyproperty(name = "__code__")] + #[pyproperty(magic)] fn code(&self, _vm: &VirtualMachine) -> PyCodeRef { self.code.clone() } - #[pyproperty(name = "__defaults__")] + #[pyproperty(magic)] fn defaults(&self, _vm: &VirtualMachine) -> Option { self.defaults.clone() } - #[pyproperty(name = "__kwdefaults__")] + #[pyproperty(magic)] fn kwdefaults(&self, _vm: &VirtualMachine) -> Option { self.kw_only_defaults.clone() } diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index acb2cc70cc..3af40eef9f 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -626,6 +626,7 @@ impl PyInt { } #[pyproperty] fn real(&self, vm: &VirtualMachine) -> PyObjectRef { + // subclasses must return int here vm.ctx.new_bigint(&self.value) } diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index 5ca39913fc..7d5cafaeab 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -145,6 +145,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() From facabfee1ac0ca5f5e2337a2e2aff253ce3810ee Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 6 Feb 2020 01:22:50 +0900 Subject: [PATCH 20/26] Remove PropertyBuilder and add new_getset --- derive/src/pyclass.rs | 3 +- vm/src/exceptions.rs | 40 ++++++------- vm/src/obj/objcode.rs | 22 +++---- vm/src/obj/objproperty.rs | 116 ++---------------------------------- vm/src/obj/objtype.rs | 46 +++++--------- vm/src/pyobject.rs | 20 +++++-- vm/src/stdlib/io.rs | 12 ++-- vm/src/stdlib/os.rs | 4 +- vm/src/stdlib/pwd.rs | 14 ++--- vm/src/stdlib/subprocess.rs | 12 ++-- 10 files changed, 86 insertions(+), 203 deletions(-) diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index b7bdff2c2d..b5894ce9b9 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -692,7 +692,8 @@ pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result 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)), }); 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, { @@ -665,27 +661,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)), }); } diff --git a/vm/src/obj/objcode.rs b/vm/src/obj/objcode.rs index cfb634c8b1..b84e50c0e8 100644 --- a/vm/src/obj/objcode.rs +++ b/vm/src/obj/objcode.rs @@ -92,17 +92,17 @@ impl PyCodeRef { } } -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), - - "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), + "__repr__" => ctx.new_method(PyCodeRef::repr), + + "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), }); } diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index cc945f96bd..7bc683bc27 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -4,52 +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::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; - -impl SlotDescriptor for PyReadOnlyProperty { - fn descr_get( - vm: &VirtualMachine, - zelf: PyObjectRef, - obj: Option, - cls: OptionalArg, - ) -> PyResult { - let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?; - 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(SlotDescriptor))] -impl PyReadOnlyProperty {} - /// Property attribute. /// /// fget @@ -255,81 +216,12 @@ fn py_none_to_option(vm: &VirtualMachine, value: &PyObjectRef) -> Option { - ctx: &'a PyContext, - getter: Option, - setter: Option, -} - -impl<'a> PropertyBuilder<'a> { - pub fn new(ctx: &'a PyContext) -> Self { - Self { - ctx, - getter: None, - setter: None, - } - } - - pub fn add_getter>(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 super::objgetset::IntoPyNoResult, 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), }); } diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index 7d5cafaeab..4a4a6b6d32 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -5,7 +5,6 @@ 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; @@ -80,16 +79,13 @@ impl PyClassRef { } } - fn _mro(self, _vm: &VirtualMachine) -> PyTuple { + #[pyproperty(name = "__mro__")] + fn get_mro(self, _vm: &VirtualMachine) -> PyTuple { let elements: Vec = _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_owned())) - } - #[pyproperty(magic)] fn bases(self, vm: &VirtualMachine) -> PyObjectRef { vm.ctx @@ -338,6 +334,18 @@ impl PyClassRef { } 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(), + )) + } } /* @@ -346,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 { @@ -409,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_owned(), - )) -} - impl PyClassRef { /// This is the internal get_attr implementation for fast lookup on a class. pub fn get_attr(&self, attr_name: &str) -> Option { diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 555d480bd4..b42be1ba80 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -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}; @@ -503,11 +503,23 @@ impl PyContext { ) } - pub fn new_property(&self, f: F) -> PyObjectRef + pub fn new_readonly_getset(&self, name: impl Into, f: F) -> PyObjectRef where - F: IntoPyNativeFunc, + F: IntoPyGetterFunc, { - PropertyBuilder::new(self).add_getter(f).create() + PyObject::new(PyGetSet::with_get(name.into(), f), self.getset_type(), None) + } + + pub fn new_getset(&self, name: impl Into, g: G, s: S) -> PyObjectRef + where + G: IntoPyGetterFunc, + S: IntoPySetterFunc, + { + PyObject::new( + PyGetSet::with_get_set(name.into(), g, s), + self.getset_type(), + None, + ) } pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyCodeRef { diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 378fe5f4f1..cc43860e24 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -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()) } @@ -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,7 +676,7 @@ 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(()) } @@ -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), }); diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index a6be3e5262..b96ec766d5 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -1235,8 +1235,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), diff --git a/vm/src/stdlib/pwd.rs b/vm/src/stdlib/pwd.rs index ecff167b84..0ad3942a49 100644 --- a/vm/src/stdlib/pwd.rs +++ b/vm/src/stdlib/pwd.rs @@ -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", { diff --git a/vm/src/stdlib/subprocess.rs b/vm/src/stdlib/subprocess.rs index 78e8bfafc5..35ae5115a7 100644 --- a/vm/src/stdlib/subprocess.rs +++ b/vm/src/stdlib/subprocess.rs @@ -253,18 +253,18 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let popen = py_class!(ctx, "Popen", ctx.object(), { (slot new) => PopenRef::new, "poll" => ctx.new_method(PopenRef::poll), - "returncode" => ctx.new_property(PopenRef::return_code), + "returncode" => ctx.new_readonly_getset("returncode", PopenRef::return_code), "wait" => ctx.new_method(PopenRef::wait), - "stdin" => ctx.new_property(PopenRef::stdin), - "stdout" => ctx.new_property(PopenRef::stdout), - "stderr" => ctx.new_property(PopenRef::stderr), + "stdin" => ctx.new_readonly_getset("stdin", PopenRef::stdin), + "stdout" => ctx.new_readonly_getset("stdout", PopenRef::stdout), + "stderr" => ctx.new_readonly_getset("stderr", PopenRef::stderr), "terminate" => ctx.new_method(PopenRef::terminate), "kill" => ctx.new_method(PopenRef::kill), "communicate" => ctx.new_method(PopenRef::communicate), - "pid" => ctx.new_property(PopenRef::pid), + "pid" => ctx.new_readonly_getset("pid", PopenRef::pid), "__enter__" => ctx.new_method(PopenRef::enter), "__exit__" => ctx.new_method(PopenRef::exit), - "args" => ctx.new_property(PopenRef::args), + "args" => ctx.new_readonly_getset("args", PopenRef::args), }); py_module!(vm, "_subprocess", { From 58744df1d594fd06a8211b9c3c1014514b1ed230 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 1 Feb 2020 22:59:45 +0900 Subject: [PATCH 21/26] Revert 08e66b5002f3a3a30db72b350b18c61d367ef1fc which is not required anymore --- vm/src/obj/objnone.rs | 65 +-------------------------------------- vm/src/obj/objproperty.rs | 9 ------ 2 files changed, 1 insertion(+), 73 deletions(-) diff --git a/vm/src/obj/objnone.rs b/vm/src/obj/objnone.rs index 51984923d0..cb42e879e7 100644 --- a/vm/src/obj/objnone.rs +++ b/vm/src/obj/objnone.rs @@ -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; @@ -52,66 +49,6 @@ impl PyNone { Ok(false) } - #[pymethod(name = "__getattribute__")] - fn get_attribute(zelf: PyRef, 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) { diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index 7bc683bc27..eb550ac71c 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -107,15 +107,6 @@ 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_owned())) - } - } - #[pymethod(name = "__set__")] fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult { if let Some(ref setter) = self.setter.as_ref() { From c0b235ed66f80ac71b7a13f76e198c18ea862411 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sun, 2 Feb 2020 23:41:38 +0900 Subject: [PATCH 22/26] cleanup property and get descriptor codes --- vm/src/obj/objproperty.rs | 13 +++++++------ vm/src/obj/objsuper.rs | 2 +- vm/src/obj/objtype.rs | 2 +- vm/src/vm.rs | 38 +++++++++++++++++++++----------------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index eb550ac71c..cb6c21cd1c 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -73,6 +73,7 @@ struct PropertyArgs { } impl SlotDescriptor for PyProperty { + #[allow(clippy::collapsible_if)] fn descr_get( vm: &VirtualMachine, zelf: PyObjectRef, @@ -80,14 +81,14 @@ impl SlotDescriptor for PyProperty { _cls: OptionalArg, ) -> PyResult { let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?; - if let Some(getter) = zelf.getter.as_ref() { - if obj.is(vm.ctx.none.as_object()) { - Ok(zelf.into_object()) - } else { + if vm.is_none(&obj) { + Ok(zelf.into_object()) + } else { + if let Some(getter) = zelf.getter.as_ref() { vm.invoke(&getter, obj) + } else { + Err(vm.new_attribute_error("unreadable attribute".to_string())) } - } else { - Err(vm.new_attribute_error("unreadable attribute".to_owned())) } } } diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs index a9b5aed07e..89520235b8 100644 --- a/vm/src/obj/objsuper.rs +++ b/vm/src/obj/objsuper.rs @@ -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!( diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index 4a4a6b6d32..922993c985 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -185,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 { diff --git a/vm/src/vm.rs b/vm/src/vm.rs index ca6cce10da..53ef276cf7 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -618,23 +618,28 @@ impl VirtualMachine { objbool::boolval(self, ret) } - pub fn call_get_descriptor(&self, attr: PyObjectRef, obj: PyObjectRef) -> PyResult { - let attr_class = attr.class(); - let slots = attr_class.slots.borrow(); - if let Some(descr_get) = slots.borrow().descr_get.as_ref() { + pub fn call_get_descriptor(&self, descr: PyObjectRef, obj: PyObjectRef) -> Option { + let descr_class = descr.class(); + let slots = descr_class.slots.borrow(); + Some(if let Some(descr_get) = slots.borrow().descr_get.as_ref() { let cls = obj.class(); descr_get( self, - attr, + descr, Some(obj.clone()), OptionalArg::Present(cls.into_object()), ) - } else if let Some(ref descriptor) = attr_class.get_attr("__get__") { + } else if let Some(ref descriptor) = descr_class.get_attr("__get__") { let cls = obj.class(); - self.invoke(descriptor, vec![attr, obj.clone(), cls.into_object()]) + self.invoke(descriptor, vec![descr, obj.clone(), cls.into_object()]) } else { - Ok(attr) - } + return None; + }) + } + + pub fn call_if_get_descriptor(&self, attr: PyObjectRef, obj: PyObjectRef) -> PyResult { + self.call_get_descriptor(attr.clone(), obj) + .unwrap_or(Ok(attr)) } pub fn call_method(&self, obj: &PyObjectRef, method_name: &str, args: T) -> PyResult @@ -654,7 +659,7 @@ impl VirtualMachine { method_name, func ); - let wrapped = self.call_get_descriptor(func, obj.clone())?; + let wrapped = self.call_if_get_descriptor(func, obj.clone())?; self.invoke(&wrapped, args) } None => Err(self.new_type_error(format!("Unsupported method: {}", method_name))), @@ -787,7 +792,7 @@ impl VirtualMachine { { let cls = obj.class(); match cls.get_attr(method_name) { - Some(method) => self.call_get_descriptor(method, obj.clone()), + Some(method) => self.call_if_get_descriptor(method, obj.clone()), None => Err(self.new_type_error(err_msg())), } } @@ -796,7 +801,7 @@ impl VirtualMachine { pub fn get_method(&self, obj: PyObjectRef, method_name: &str) -> Option { let cls = obj.class(); let method = cls.get_attr(method_name)?; - Some(self.call_get_descriptor(method, obj.clone())) + Some(self.call_if_get_descriptor(method, obj.clone())) } /// Calls a method on `obj` passing `arg`, if the method exists. @@ -848,6 +853,7 @@ impl VirtualMachine { }) } + /// CPython _PyObject_GenericGetAttrWithDict pub fn generic_getattribute( &self, obj: PyObjectRef, @@ -859,10 +865,8 @@ impl VirtualMachine { if let Some(attr) = cls.get_attr(&name) { let attr_class = attr.class(); if attr_class.has_attr("__set__") { - if let Some(descriptor) = attr_class.get_attr("__get__") { - return self - .invoke(&descriptor, vec![attr, obj, cls.into_object()]) - .map(Some); + if let Some(r) = self.call_get_descriptor(attr, obj.clone()) { + return r.map(Some); } } } @@ -876,7 +880,7 @@ impl VirtualMachine { if let Some(obj_attr) = attr { Ok(Some(obj_attr)) } else if let Some(attr) = cls.get_attr(&name) { - self.call_get_descriptor(attr, obj).map(Some) + self.call_if_get_descriptor(attr, obj).map(Some) } else if let Some(getter) = cls.get_attr("__getattr__") { self.invoke(&getter, vec![obj, name_str.into_object()]) .map(Some) From 429a27640d6145e7021083cc4c988788a570b13e Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sun, 26 Jan 2020 02:05:45 +0900 Subject: [PATCH 23/26] Bump up to python 3.8 for Azure Pipelines --- azure-pipelines.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 55f2f3a1e6..2bc1864dbe 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -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: | From 844b6395cec0f9ad65a2a082e7b7e458d9069193 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 6 Feb 2020 01:22:50 +0900 Subject: [PATCH 24/26] Fix SyntaxError initial value --- tests/snippets/exceptions.py | 8 ++++++++ vm/src/exceptions.rs | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/tests/snippets/exceptions.py b/tests/snippets/exceptions.py index 8ade9c8de2..c0c3e4ab86 100644 --- a/tests/snippets/exceptions.py +++ b/tests/snippets/exceptions.py @@ -65,3 +65,11 @@ def __init__(self, value): 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 diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 1ea9469b16..305483ec43 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -645,6 +645,11 @@ pub fn init(ctx: &PyContext) { extend_class!(ctx, &excs.syntax_error, { "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, { From 6ddb690e09ca5723cb4c770bf40e16877ba7a1f8 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 6 Feb 2020 02:07:22 +0900 Subject: [PATCH 25/26] Remove `_vm` parameter when it is not required --- vm/src/builtins.rs | 6 +- vm/src/exceptions.rs | 28 +++----- vm/src/frame.rs | 2 +- vm/src/obj/objbool.rs | 2 +- vm/src/obj/objbytearray.rs | 75 +++++++++------------ vm/src/obj/objbytes.rs | 55 ++++++++-------- vm/src/obj/objclassmethod.rs | 2 +- vm/src/obj/objcode.rs | 14 ++-- vm/src/obj/objcomplex.rs | 16 ++--- vm/src/obj/objcoroutine.rs | 4 +- vm/src/obj/objdict.rs | 28 ++++---- vm/src/obj/objellipsis.rs | 4 +- vm/src/obj/objenumerate.rs | 2 +- vm/src/obj/objfilter.rs | 2 +- vm/src/obj/objfloat.rs | 26 ++++---- vm/src/obj/objframe.rs | 10 +-- vm/src/obj/objfunction.rs | 6 +- vm/src/obj/objgenerator.rs | 2 +- vm/src/obj/objint.rs | 36 +++++------ vm/src/obj/objiter.rs | 4 +- vm/src/obj/objlist.rs | 28 ++++---- vm/src/obj/objmap.rs | 2 +- vm/src/obj/objnone.rs | 4 +- vm/src/obj/objobject.rs | 16 ++--- vm/src/obj/objproperty.rs | 8 +-- vm/src/obj/objrange.rs | 30 ++++----- vm/src/obj/objset.rs | 14 ++-- vm/src/obj/objslice.rs | 16 ++--- vm/src/obj/objstr.rs | 118 ++++++++++++++-------------------- vm/src/obj/objsuper.rs | 2 +- vm/src/obj/objtraceback.rs | 8 +-- vm/src/obj/objtuple.rs | 16 ++--- vm/src/obj/objtype.rs | 12 ++-- vm/src/obj/objzip.rs | 2 +- vm/src/stdlib/array.rs | 16 ++--- vm/src/stdlib/binascii.rs | 8 +-- vm/src/stdlib/collections.rs | 28 ++++---- vm/src/stdlib/faulthandler.rs | 3 +- vm/src/stdlib/hashlib.rs | 6 +- vm/src/stdlib/imp.rs | 4 +- vm/src/stdlib/io.rs | 32 ++++----- vm/src/stdlib/itertools.rs | 36 +++++------ vm/src/stdlib/marshal.rs | 2 +- vm/src/stdlib/math.rs | 36 +++++------ vm/src/stdlib/os.rs | 25 ++++--- vm/src/stdlib/pwd.rs | 14 ++-- vm/src/stdlib/re.rs | 2 +- vm/src/stdlib/signal.rs | 2 +- vm/src/stdlib/socket.rs | 14 ++-- vm/src/stdlib/subprocess.rs | 11 ++-- vm/src/stdlib/symtable.rs | 24 +++---- vm/src/stdlib/thread.rs | 2 +- vm/src/stdlib/time_module.rs | 4 +- vm/src/stdlib/unicodedata.rs | 2 +- vm/src/stdlib/weakref.rs | 4 +- vm/src/sysmodule.rs | 6 +- vm/src/vm.rs | 2 +- wasm/lib/src/js_module.rs | 20 +++--- 58 files changed, 421 insertions(+), 482 deletions(-) diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 72891812cf..bfa1a01f4a 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -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()) @@ -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 { 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 { diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 1ea9469b16..83023d9d2e 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -68,7 +68,7 @@ impl PyBaseException { } #[pyproperty(name = "args")] - fn get_args(&self, _vm: &VirtualMachine) -> PyTupleRef { + fn get_args(&self) -> PyTupleRef { self.args.borrow().clone() } @@ -90,51 +90,39 @@ impl PyBaseException { } #[pyproperty(name = "__cause__")] - fn get_cause(&self, _vm: &VirtualMachine) -> Option { + fn get_cause(&self) -> Option { self.cause.borrow().clone() } #[pyproperty(name = "__cause__", setter)] - fn setter_cause( - &self, - cause: Option, - _vm: &VirtualMachine, - ) -> PyResult<()> { + fn setter_cause(&self, cause: Option) -> PyResult<()> { self.cause.replace(cause); Ok(()) } #[pyproperty(name = "__context__")] - fn get_context(&self, _vm: &VirtualMachine) -> Option { + fn get_context(&self) -> Option { self.context.borrow().clone() } #[pyproperty(name = "__context__", setter)] - fn setter_context( - &self, - context: Option, - _vm: &VirtualMachine, - ) -> PyResult<()> { + fn setter_context(&self, context: Option) -> PyResult<()> { self.context.replace(context); Ok(()) } #[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, - tb: Option, - _vm: &VirtualMachine, - ) -> PyResult { + fn with_traceback(zelf: PyRef, tb: Option) -> PyResult { zelf.traceback.replace(tb); Ok(zelf.as_object().clone()) } diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 4466bc881f..61b4abe12c 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -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 } => { diff --git a/vm/src/obj/objbool.rs b/vm/src/obj/objbool.rs index 264d305999..1cd91e9b9d 100644 --- a/vm/src/obj/objbool.rs +++ b/vm/src/obj/objbool.rs @@ -118,7 +118,7 @@ pub fn get_py_int(obj: &PyObjectRef) -> &PyInt { &obj.payload::().unwrap() } -fn bool_repr(obj: bool, _vm: &VirtualMachine) -> String { +fn bool_repr(obj: bool) -> String { if obj { "True".to_owned() } else { diff --git a/vm/src/obj/objbytearray.rs b/vm/src/obj/objbytearray.rs index 73e5d9d5d4..440749730e 100644 --- a/vm/src/obj/objbytearray.rs +++ b/vm/src/obj/objbytearray.rs @@ -99,17 +99,17 @@ impl PyByteArray { } #[pymethod(name = "__repr__")] - fn repr(&self, _vm: &VirtualMachine) -> PyResult { + fn repr(&self) -> PyResult { 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.inner.borrow().len() * size_of::() } @@ -144,7 +144,7 @@ impl PyByteArray { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyByteArrayIterator { + fn iter(zelf: PyRef) -> 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() } @@ -375,11 +375,7 @@ impl PyByteArray { } #[pymethod(name = "strip")] - fn strip( - &self, - chars: OptionalArg, - _vm: &VirtualMachine, - ) -> PyResult { + fn strip(&self, chars: OptionalArg) -> PyResult { Ok(self .inner .borrow() @@ -388,11 +384,7 @@ impl PyByteArray { } #[pymethod(name = "lstrip")] - fn lstrip( - &self, - chars: OptionalArg, - _vm: &VirtualMachine, - ) -> PyResult { + fn lstrip(&self, chars: OptionalArg) -> PyResult { Ok(self .inner .borrow() @@ -401,11 +393,7 @@ impl PyByteArray { } #[pymethod(name = "rstrip")] - fn rstrip( - &self, - chars: OptionalArg, - _vm: &VirtualMachine, - ) -> PyResult { + fn rstrip(&self, chars: OptionalArg) -> PyResult { 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, - _vm: &VirtualMachine, ) -> PyResult { 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() } @@ -560,22 +547,22 @@ impl PyByteArray { } #[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, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/obj/objbytes.rs b/vm/src/obj/objbytes.rs index 99a9c6a26f..07a333a934 100644 --- a/vm/src/obj/objbytes.rs +++ b/vm/src/obj/objbytes.rs @@ -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, _vm: &VirtualMachine) -> PyBytesIterator { + fn iter(zelf: PyRef) -> PyBytesIterator { PyBytesIterator { position: Cell::new(0), bytes: zelf, @@ -148,7 +148,7 @@ impl PyBytes { } #[pymethod(name = "__sizeof__")] - fn sizeof(&self, _vm: &VirtualMachine) -> PyResult { + fn sizeof(&self) -> PyResult { Ok(size_of::() + self.inner.elements.len() * size_of::()) } @@ -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() } @@ -330,17 +330,17 @@ impl PyBytes { } #[pymethod(name = "strip")] - fn strip(&self, chars: OptionalArg, _vm: &VirtualMachine) -> PyResult { + fn strip(&self, chars: OptionalArg) -> PyResult { Ok(self.inner.strip(chars, ByteInnerPosition::All)?.into()) } #[pymethod(name = "lstrip")] - fn lstrip(&self, chars: OptionalArg, _vm: &VirtualMachine) -> PyResult { + fn lstrip(&self, chars: OptionalArg) -> PyResult { Ok(self.inner.strip(chars, ByteInnerPosition::Left)?.into()) } #[pymethod(name = "rstrip")] - fn rstrip(&self, chars: OptionalArg, _vm: &VirtualMachine) -> PyResult { + fn rstrip(&self, chars: OptionalArg) -> PyResult { 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, - _vm: &VirtualMachine, ) -> PyResult { 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, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/obj/objclassmethod.rs b/vm/src/obj/objclassmethod.rs index 8c3d5070d2..edc579698c 100644 --- a/vm/src/obj/objclassmethod.rs +++ b/vm/src/obj/objclassmethod.rs @@ -75,7 +75,7 @@ impl PyClassMethod { } #[pyproperty(name = "__func__")] - fn func(&self, _vm: &VirtualMachine) -> PyObjectRef { + fn func(&self) -> PyObjectRef { self.callable.clone() } } diff --git a/vm/src/obj/objcode.rs b/vm/src/obj/objcode.rs index b84e50c0e8..8c1d9b8e83 100644 --- a/vm/src/obj/objcode.rs +++ b/vm/src/obj/objcode.rs @@ -47,7 +47,7 @@ impl PyCodeRef { 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!( "", @@ -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,11 +83,11 @@ 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() } } diff --git a/vm/src/obj/objcomplex.rs b/vm/src/obj/objcomplex.rs index 24085c1412..fa39c17979 100644 --- a/vm/src/obj/objcomplex.rs +++ b/vm/src/obj/objcomplex.rs @@ -57,17 +57,17 @@ fn try_complex(value: &PyObjectRef, vm: &VirtualMachine) -> PyResult 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() } @@ -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); diff --git a/vm/src/obj/objcoroutine.rs b/vm/src/obj/objcoroutine.rs index eb6f1faa2c..86cf17a83e 100644 --- a/vm/src/obj/objcoroutine.rs +++ b/vm/src/obj/objcoroutine.rs @@ -105,7 +105,7 @@ impl PyCoroutine { } #[pymethod(name = "__await__")] - fn r#await(zelf: PyRef, _vm: &VirtualMachine) -> PyCoroutineWrapper { + fn r#await(zelf: PyRef) -> PyCoroutineWrapper { PyCoroutineWrapper { coro: zelf } } } @@ -125,7 +125,7 @@ impl PyValue for PyCoroutineWrapper { #[pyimpl] impl PyCoroutineWrapper { #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs index 8eca812990..bcd66d87d6 100644 --- a/vm/src/obj/objdict.rs +++ b/vm/src/obj/objdict.rs @@ -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.entries.borrow().sizeof() } @@ -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(), } @@ -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__")] @@ -579,12 +579,12 @@ macro_rules! dict_iterator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } #[pymethod(name = "__length_hint__")] - fn length_hint(&self, _vm: &VirtualMachine) -> usize { + fn length_hint(&self) -> usize { self.dict .entries .borrow() diff --git a/vm/src/obj/objellipsis.rs b/vm/src/obj/objellipsis.rs index a8a22a4da0..407a9b2661 100644 --- a/vm/src/obj/objellipsis.rs +++ b/vm/src/obj/objellipsis.rs @@ -21,10 +21,10 @@ fn ellipsis_new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult { } } -fn ellipsis_repr(_self: PyEllipsisRef, _vm: &VirtualMachine) -> String { +fn ellipsis_repr(_self: PyEllipsisRef) -> String { "Ellipsis".to_owned() } -fn ellipsis_reduce(_self: PyEllipsisRef, _vm: &VirtualMachine) -> String { +fn ellipsis_reduce(_self: PyEllipsisRef) -> String { "Ellipsis".to_owned() } diff --git a/vm/src/obj/objenumerate.rs b/vm/src/obj/objenumerate.rs index 0eddb0c610..4bbe8caccf 100644 --- a/vm/src/obj/objenumerate.rs +++ b/vm/src/obj/objenumerate.rs @@ -62,7 +62,7 @@ impl PyEnumerate { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/obj/objfilter.rs b/vm/src/obj/objfilter.rs index 482c1ab61a..1b3f2ae654 100644 --- a/vm/src/obj/objfilter.rs +++ b/vm/src/obj/objfilter.rs @@ -61,7 +61,7 @@ impl PyFilter { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/obj/objfloat.rs b/vm/src/obj/objfloat.rs index ffc8e946b6..cbb5196d79 100644 --- a/vm/src/obj/objfloat.rs +++ b/vm/src/obj/objfloat.rs @@ -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::().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, _vm: &VirtualMachine) -> PyFloatRef { + fn float(zelf: PyRef) -> PyFloatRef { zelf } #[pymethod(name = "__hash__")] - fn hash(&self, _vm: &VirtualMachine) -> pyhash::PyHash { + fn hash(&self) -> pyhash::PyHash { pyhash::hash_float(self.value) } #[pyproperty] - fn real(zelf: PyRef, _vm: &VirtualMachine) -> PyFloatRef { + fn real(zelf: PyRef) -> PyFloatRef { zelf } #[pyproperty] - fn imag(&self, _vm: &VirtualMachine) -> f64 { + fn imag(&self) -> f64 { 0.0f64 } #[pymethod(name = "conjugate")] - fn conjugate(zelf: PyRef, _vm: &VirtualMachine) -> PyFloatRef { + fn conjugate(zelf: PyRef) -> 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 } @@ -592,7 +592,7 @@ impl PyFloat { } #[pymethod] - fn hex(&self, _vm: &VirtualMachine) -> String { + fn hex(&self) -> String { to_hex(self.value) } } diff --git a/vm/src/obj/objframe.rs b/vm/src/obj/objframe.rs index 73067bd4bb..48e4191540 100644 --- a/vm/src/obj/objframe.rs +++ b/vm/src/obj/objframe.rs @@ -20,27 +20,27 @@ impl FrameRef { } #[pymethod(name = "__repr__")] - fn repr(self, _vm: &VirtualMachine) -> String { + fn repr(self) -> String { "".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() } diff --git a/vm/src/obj/objfunction.rs b/vm/src/obj/objfunction.rs index d3532d01ab..b9994712d6 100644 --- a/vm/src/obj/objfunction.rs +++ b/vm/src/obj/objfunction.rs @@ -250,17 +250,17 @@ impl PyFunction { } #[pyproperty(magic)] - fn code(&self, _vm: &VirtualMachine) -> PyCodeRef { + fn code(&self) -> PyCodeRef { self.code.clone() } #[pyproperty(magic)] - fn defaults(&self, _vm: &VirtualMachine) -> Option { + fn defaults(&self) -> Option { self.defaults.clone() } #[pyproperty(magic)] - fn kwdefaults(&self, _vm: &VirtualMachine) -> Option { + fn kwdefaults(&self) -> Option { self.kw_only_defaults.clone() } } diff --git a/vm/src/obj/objgenerator.rs b/vm/src/obj/objgenerator.rs index a42519d7fe..8d72218c4b 100644 --- a/vm/src/obj/objgenerator.rs +++ b/vm/src/obj/objgenerator.rs @@ -45,7 +45,7 @@ impl PyGenerator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyGeneratorRef, _vm: &VirtualMachine) -> PyGeneratorRef { + fn iter(zelf: PyGeneratorRef) -> PyGeneratorRef { zelf } diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index 3af40eef9f..9b5d0185b0 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -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, _vm: &VirtualMachine) -> PyIntRef { + fn int(zelf: PyRef) -> 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, _vm: &VirtualMachine) -> PyIntRef { + fn trunc(zelf: PyRef) -> PyIntRef { zelf } #[pymethod(name = "__floor__")] - fn floor(zelf: PyRef, _vm: &VirtualMachine) -> PyIntRef { + fn floor(zelf: PyRef) -> PyIntRef { zelf } #[pymethod(name = "__ceil__")] - fn ceil(zelf: PyRef, _vm: &VirtualMachine) -> PyIntRef { + fn ceil(zelf: PyRef) -> PyIntRef { zelf } #[pymethod(name = "__index__")] - fn index(zelf: PyRef, _vm: &VirtualMachine) -> PyIntRef { + fn index(zelf: PyRef) -> 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.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, _vm: &VirtualMachine) -> PyIntRef { + fn conjugate(zelf: PyRef) -> PyIntRef { zelf } @@ -631,17 +631,17 @@ impl PyInt { } #[pyproperty] - fn imag(&self, _vm: &VirtualMachine) -> usize { + fn imag(&self) -> usize { 0 } #[pyproperty] - fn numerator(zelf: PyRef, _vm: &VirtualMachine) -> PyIntRef { + fn numerator(zelf: PyRef) -> PyIntRef { zelf } #[pyproperty] - fn denominator(&self, _vm: &VirtualMachine) -> usize { + fn denominator(&self) -> usize { 1 } } diff --git a/vm/src/obj/objiter.rs b/vm/src/obj/objiter.rs index 2d98a04037..5c1e06a6bf 100644 --- a/vm/src/obj/objiter.rs +++ b/vm/src/obj/objiter.rs @@ -174,7 +174,7 @@ impl PySequenceIterator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } @@ -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, diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs index 94b8548736..db4c981ee8 100644 --- a/vm/src/obj/objlist.rs +++ b/vm/src/obj/objlist.rs @@ -147,7 +147,7 @@ pub type PyListRef = PyRef; #[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); } @@ -159,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() @@ -201,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(); } @@ -216,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.elements.borrow().capacity() * size_of::() } #[pymethod] - fn reverse(&self, _vm: &VirtualMachine) { + fn reverse(&self) { self.elements.borrow_mut().reverse(); } #[pymethod(name = "__reversed__")] - fn reversed(zelf: PyRef, _vm: &VirtualMachine) -> PyListReverseIterator { + fn reversed(zelf: PyRef) -> PyListReverseIterator { let final_position = zelf.elements.borrow().len(); PyListReverseIterator { position: Cell::new(final_position), @@ -250,7 +250,7 @@ impl PyList { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyListIterator { + fn iter(zelf: PyRef) -> PyListIterator { PyListIterator { position: Cell::new(0), list: zelf, @@ -481,7 +481,7 @@ impl PyList { } #[pymethod(name = "__imul__")] - fn imul(zelf: PyRef, counter: isize, _vm: &VirtualMachine) -> PyRef { + fn imul(zelf: PyRef, counter: isize) -> PyRef { let new_elements = sequence::seq_mul(&zelf.borrow_sequence(), counter) .cloned() .collect(); @@ -868,12 +868,12 @@ impl PyListIterator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { 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() } } @@ -906,12 +906,12 @@ impl PyListReverseIterator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } #[pymethod(name = "__length_hint__")] - fn length_hint(&self, _vm: &VirtualMachine) -> usize { + fn length_hint(&self) -> usize { self.position.get() } } diff --git a/vm/src/obj/objmap.rs b/vm/src/obj/objmap.rs index 86ff0fdc62..a90b1c025d 100644 --- a/vm/src/obj/objmap.rs +++ b/vm/src/obj/objmap.rs @@ -55,7 +55,7 @@ impl PyMap { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } diff --git a/vm/src/obj/objnone.rs b/vm/src/obj/objnone.rs index cb42e879e7..f618927e17 100644 --- a/vm/src/obj/objnone.rs +++ b/vm/src/obj/objnone.rs @@ -40,12 +40,12 @@ impl PyNone { } #[pymethod(name = "__repr__")] - fn repr(&self, _vm: &VirtualMachine) -> PyResult { + fn repr(&self) -> PyResult { Ok("None".to_owned()) } #[pymethod(name = "__bool__")] - fn bool(&self, _vm: &VirtualMachine) -> PyResult { + fn bool(&self) -> PyResult { Ok(false) } diff --git a/vm/src/obj/objobject.rs b/vm/src/obj/objobject.rs index bafec4abbe..5878108c69 100644 --- a/vm/src/obj/objobject.rs +++ b/vm/src/obj/objobject.rs @@ -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,7 +175,7 @@ impl PyBaseObject { } #[pyproperty(name = "__class__")] - fn get_class(obj: PyObjectRef, _vm: &VirtualMachine) -> PyObjectRef { + fn get_class(obj: PyObjectRef) -> PyObjectRef { obj.class().into_object() } diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index cb6c21cd1c..f97c9a8ed3 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -129,21 +129,21 @@ impl PyProperty { // Access functions #[pyproperty] - fn fget(&self, _vm: &VirtualMachine) -> Option { + fn fget(&self) -> Option { self.getter.clone() } #[pyproperty] - fn fset(&self, _vm: &VirtualMachine) -> Option { + fn fset(&self) -> Option { self.setter.clone() } #[pyproperty] - fn fdel(&self, _vm: &VirtualMachine) -> Option { + fn fdel(&self) -> Option { self.deleter.clone() } - fn doc_getter(&self, _vm: &VirtualMachine) -> Option { + fn doc_getter(&self) -> Option { self.doc.borrow().clone() } diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs index 569dc4b472..a0dc60d27e 100644 --- a/vm/src/obj/objrange.rs +++ b/vm/src/obj/objrange.rs @@ -154,22 +154,22 @@ impl PyRange { } #[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, _vm: &VirtualMachine) -> PyRangeIterator { + fn iter(zelf: PyRef) -> 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::() { match self.offset(int.as_bigint()) { Some(ref offset) => offset.is_multiple_of(self.step.as_bigint()), @@ -323,7 +323,7 @@ impl PyRange { } #[pymethod(name = "count")] - fn count(&self, item: PyObjectRef, _vm: &VirtualMachine) -> usize { + fn count(&self, item: PyObjectRef) -> usize { if let Ok(int) = item.downcast::() { 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(); @@ -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, _vm: &VirtualMachine) -> PyRangeIteratorRef { + fn iter(zelf: PyRef) -> PyRangeIteratorRef { zelf } } diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs index 73e48ad247..146d8511b1 100644 --- a/vm/src/obj/objset.rs +++ b/vm/src/obj/objset.rs @@ -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.inner.borrow().sizeof() } #[pymethod] - fn copy(&self, _vm: &VirtualMachine) -> Self { + fn copy(&self) -> Self { Self { inner: RefCell::new(self.inner.borrow().copy()), } @@ -513,7 +513,7 @@ impl PySet { } #[pymethod] - fn clear(&self, _vm: &VirtualMachine) { + fn clear(&self) { self.inner.borrow_mut().clear() } @@ -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.inner.sizeof() } #[pymethod] - fn copy(&self, _vm: &VirtualMachine) -> Self { + fn copy(&self) -> Self { Self { inner: self.inner.copy(), } diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs index 51ceb237da..3c21ea7890 100644 --- a/vm/src/obj/objslice.rs +++ b/vm/src/obj/objslice.rs @@ -51,14 +51,14 @@ impl PySlice { } #[pymethod(name = "__repr__")] - fn repr(&self, _vm: &VirtualMachine) -> PyResult { - 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)?; + fn repr(&self, vm: &VirtualMachine) -> PyResult { + 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)?; Ok(format!( "slice({}, {}, {})", diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs index 9be0512307..a2c8acc0b4 100644 --- a/vm/src/obj/objstr.rs +++ b/vm/src/obj/objstr.rs @@ -127,7 +127,7 @@ impl PyStringIterator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -163,7 +163,7 @@ impl PyStringReverseIterator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { 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) } @@ -285,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 => { @@ -317,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.value.capacity() * size_of::() } @@ -343,12 +343,12 @@ impl PyString { } #[pymethod(name = "__str__")] - fn str(zelf: PyRef, _vm: &VirtualMachine) -> PyStringRef { + fn str(zelf: PyRef) -> 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, '"') { '"' @@ -390,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) } @@ -471,7 +471,7 @@ impl PyString { } #[pymethod] - fn strip(&self, chars: OptionalArg, _vm: &VirtualMachine) -> String { + fn strip(&self, chars: OptionalArg) -> String { let chars = match chars { OptionalArg::Present(ref chars) => &chars.value, OptionalArg::Missing => return self.value.trim().to_owned(), @@ -480,7 +480,7 @@ impl PyString { } #[pymethod] - fn lstrip(&self, chars: OptionalArg, _vm: &VirtualMachine) -> String { + fn lstrip(&self, chars: OptionalArg) -> String { let chars = match chars { OptionalArg::Present(ref chars) => &chars.value, OptionalArg::Missing => return self.value.trim_start().to_owned(), @@ -491,7 +491,7 @@ impl PyString { } #[pymethod] - fn rstrip(&self, chars: OptionalArg, _vm: &VirtualMachine) -> String { + fn rstrip(&self, chars: OptionalArg) -> String { let chars = match chars { OptionalArg::Present(ref chars) => &chars.value, OptionalArg::Missing => return self.value.trim_end().to_owned(), @@ -554,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, @@ -581,7 +581,7 @@ impl PyString { } #[pymethod] - fn isdecimal(&self, _vm: &VirtualMachine) -> bool { + fn isdecimal(&self) -> bool { if self.value.is_empty() { false } else { @@ -660,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() { @@ -687,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 @@ -703,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, - _vm: &VirtualMachine, - ) -> String { + fn replace(&self, old: PyStringRef, new: PyStringRef, num: OptionalArg) -> String { match num.into_option() { Some(num) => self.value.replacen(&old.value, &new.value, num), None => self.value.replace(&old.value, &new.value), @@ -737,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)) @@ -746,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() { @@ -766,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() { @@ -779,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()) } @@ -821,13 +815,7 @@ impl PyString { } #[pymethod] - fn find( - &self, - sub: PyStringRef, - start: OptionalArg, - end: OptionalArg, - _vm: &VirtualMachine, - ) -> isize { + fn find(&self, sub: PyStringRef, start: OptionalArg, end: OptionalArg) -> isize { let value = &self.value; if let Some((start, end)) = adjust_indices(start, end, value.len()) { match value[start..end].find(&sub.value) { @@ -840,13 +828,7 @@ impl PyString { } #[pymethod] - fn rfind( - &self, - sub: PyStringRef, - start: OptionalArg, - end: OptionalArg, - _vm: &VirtualMachine, - ) -> isize { + fn rfind(&self, sub: PyStringRef, start: OptionalArg, end: OptionalArg) -> isize { let value = &self.value; if let Some((start, end)) = adjust_indices(start, end, value.len()) { match value[start..end].rfind(&sub.value) { @@ -938,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; } @@ -966,13 +948,7 @@ impl PyString { } #[pymethod] - fn count( - &self, - sub: PyStringRef, - start: OptionalArg, - end: OptionalArg, - _vm: &VirtualMachine, - ) -> usize { + fn count(&self, sub: PyStringRef, start: OptionalArg, end: OptionalArg) -> usize { let value = &self.value; if let Some((start, end)) = adjust_indices(start, end, value.len()) { self.value[start..end].matches(&sub.value).count() @@ -982,7 +958,7 @@ 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_owned() @@ -1073,7 +1049,7 @@ impl PyString { } #[pymethod] - fn expandtabs(&self, tab_stop: OptionalArg, _vm: &VirtualMachine) -> String { + fn expandtabs(&self, tab_stop: OptionalArg) -> 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::() { 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::() { - 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, _vm: &VirtualMachine) -> PyStringIterator { + fn iter(zelf: PyRef) -> PyStringIterator { PyStringIterator { byte_position: Cell::new(0), string: zelf, @@ -1222,7 +1198,7 @@ impl PyString { } #[pymethod(name = "__reversed__")] - fn reversed(zelf: PyRef, _vm: &VirtualMachine) -> PyStringReverseIterator { + fn reversed(zelf: PyRef) -> PyStringReverseIterator { let begin = zelf.value.chars().count(); PyStringReverseIterator { @@ -1735,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); } } @@ -1753,7 +1729,7 @@ mod tests { ]; for s in pos { - assert!(PyString::from(s).istitle(&vm)); + assert!(PyString::from(s).istitle()); } let neg = vec![ @@ -1766,7 +1742,7 @@ mod tests { "NOT", ]; for s in neg { - assert!(!PyString::from(s).istitle(&vm)); + assert!(!PyString::from(s).istitle()); } } diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs index 89520235b8..0fcc7fd833 100644 --- a/vm/src/obj/objsuper.rs +++ b/vm/src/obj/objsuper.rs @@ -35,7 +35,7 @@ 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::() { type_class.name.clone() } else { diff --git a/vm/src/obj/objtraceback.rs b/vm/src/obj/objtraceback.rs index 4a49bebecb..ff49abbf19 100644 --- a/vm/src/obj/objtraceback.rs +++ b/vm/src/obj/objtraceback.rs @@ -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 { + fn next_get(&self) -> Option { self.next.as_ref().cloned() } } diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs index 27be3b3607..d868216a6f 100644 --- a/vm/src/obj/objtuple.rs +++ b/vm/src/obj/objtuple.rs @@ -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, _vm: &VirtualMachine) -> PyTupleIterator { + fn iter(zelf: PyRef) -> 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() } @@ -191,18 +191,14 @@ impl PyTuple { } #[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, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { get_item(vm, zelf.as_object(), &zelf.elements, needle.clone()) @@ -271,7 +267,7 @@ impl PyTupleIterator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index 922993c985..3d5f75ca5a 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -80,7 +80,7 @@ impl PyClassRef { } #[pyproperty(name = "__mro__")] - fn get_mro(self, _vm: &VirtualMachine) -> PyTuple { + fn get_mro(self) -> PyTuple { let elements: Vec = _mro(&self).iter().map(|x| x.as_object().clone()).collect(); PyTuple::from(elements) @@ -103,22 +103,22 @@ impl PyClassRef { } #[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!("", self.name) } @@ -239,7 +239,7 @@ impl PyClassRef { } #[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( diff --git a/vm/src/obj/objzip.rs b/vm/src/obj/objzip.rs index bc024cd42a..751a9731f7 100644 --- a/vm/src/obj/objzip.rs +++ b/vm/src/obj/objzip.rs @@ -45,7 +45,7 @@ impl PyZip { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/stdlib/array.rs b/vm/src/stdlib/array.rs index 970d817f86..9ea0d5bf5d 100644 --- a/vm/src/stdlib/array.rs +++ b/vm/src/stdlib/array.rs @@ -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 { + fn tobytes(&self) -> Vec { 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, _vm: &VirtualMachine) -> PyArrayIter { + fn iter(zelf: PyRef) -> PyArrayIter { PyArrayIter { position: Cell::new(0), array: zelf, @@ -394,7 +394,7 @@ impl PyArrayIter { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/stdlib/binascii.rs b/vm/src/stdlib/binascii.rs index 6b4469660d..18db3e7d96 100644 --- a/vm/src/stdlib/binascii.rs +++ b/vm/src/stdlib/binascii.rs @@ -56,7 +56,7 @@ fn hex_nibble(n: u8) -> u8 { } } -fn binascii_hexlify(data: PyBytesLike, _vm: &VirtualMachine) -> Vec { +fn binascii_hexlify(data: PyBytesLike) -> Vec { data.with_ref(|bytes| { let mut hex = Vec::::with_capacity(bytes.len() * 2); for b in bytes.iter() { @@ -124,11 +124,7 @@ fn binascii_a2b_base64(s: SerializedData, vm: &VirtualMachine) -> PyResult Vec { +fn binascii_b2a_base64(data: PyBytesLike, NewlineArg { newline }: NewlineArg) -> Vec { let mut encoded = data.with_ref(base64::encode).into_bytes(); if newline { encoded.push(b'\n'); diff --git a/vm/src/stdlib/collections.rs b/vm/src/stdlib/collections.rs index 245fc19695..5a5c6b9ead 100644 --- a/vm/src/stdlib/collections.rs +++ b/vm/src/stdlib/collections.rs @@ -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(()) } @@ -191,13 +191,13 @@ impl PyDeque { } #[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, _vm: &VirtualMachine) { + fn rotate(&self, mid: OptionalArg) { 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 { + fn maxlen(&self) -> Option { self.maxlen.get() } #[pyproperty(setter)] - fn set_maxlen(&self, maxlen: Option, _vm: &VirtualMachine) { + fn set_maxlen(&self, maxlen: Option) { self.maxlen.set(maxlen); } @@ -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, _vm: &VirtualMachine) -> PyDequeIterator { + fn iter(zelf: PyRef) -> PyDequeIterator { PyDequeIterator { position: Cell::new(0), deque: zelf, @@ -382,7 +382,7 @@ impl PyDequeIterator { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/stdlib/faulthandler.rs b/vm/src/stdlib/faulthandler.rs index d8d4b71660..9fe27cbc08 100644 --- a/vm/src/stdlib/faulthandler.rs +++ b/vm/src/stdlib/faulthandler.rs @@ -20,7 +20,7 @@ fn dump_traceback(_file: OptionalArg, _all_threads: OptionalArg, vm: } } -fn enable(_file: OptionalArg, _all_threads: OptionalArg, _vm: &VirtualMachine) { +fn enable(_file: OptionalArg, _all_threads: OptionalArg) { // TODO } @@ -29,7 +29,6 @@ fn register( _file: OptionalArg, _all_threads: OptionalArg, _chain: OptionalArg, - _vm: &VirtualMachine, ) { // TODO } diff --git a/vm/src/stdlib/hashlib.rs b/vm/src/stdlib/hashlib.rs index 98a7ce9dd9..318994e450 100644 --- a/vm/src/stdlib/hashlib.rs +++ b/vm/src/stdlib/hashlib.rs @@ -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) } diff --git a/vm/src/stdlib/imp.rs b/vm/src/stdlib/imp.rs index 4274121b47..ee0d78de65 100644 --- a/vm/src/stdlib/imp.rs +++ b/vm/src/stdlib/imp.rs @@ -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 bool { + fn seekable(self) -> bool { true } @@ -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); } } @@ -271,7 +271,7 @@ impl PyBytesIORef { } } - fn seekable(self, _vm: &VirtualMachine) -> bool { + fn seekable(self) -> bool { true } @@ -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 } @@ -435,7 +435,7 @@ fn io_base_checkseekable( } } -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 } @@ -680,7 +680,7 @@ mod fileio { 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 } diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index e0a104041d..f7ba1d336d 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -67,7 +67,7 @@ impl PyItertoolsChain { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } @@ -134,7 +134,7 @@ impl PyItertoolsCompress { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -178,14 +178,14 @@ impl PyItertoolsCount { } #[pymethod(name = "__next__")] - fn next(&self, _vm: &VirtualMachine) -> PyResult { + fn next(&self) -> PyResult { let result = self.cur.borrow().clone(); *self.cur.borrow_mut() += &self.step; Ok(PyInt::new(result)) } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -252,7 +252,7 @@ impl PyItertoolsCycle { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -304,7 +304,7 @@ impl PyItertoolsRepeat { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } @@ -353,7 +353,7 @@ impl PyItertoolsStarmap { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -412,7 +412,7 @@ impl PyItertoolsTakewhile { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -470,7 +470,7 @@ impl PyItertoolsDropwhile { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -596,7 +596,7 @@ impl PyItertoolsIslice { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -652,7 +652,7 @@ impl PyItertoolsFilterFalse { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -711,7 +711,7 @@ impl PyItertoolsAccumulate { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -810,7 +810,7 @@ impl PyItertoolsTee { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -927,7 +927,7 @@ impl PyItertoolsProduct { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } @@ -977,7 +977,7 @@ impl PyItertoolsCombinations { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } @@ -1076,7 +1076,7 @@ impl PyItertoolsCombinationsWithReplacement { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } @@ -1184,7 +1184,7 @@ impl PyItertoolsPermutations { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } @@ -1333,7 +1333,7 @@ impl PyItertoolsZiplongest { } #[pymethod(name = "__iter__")] - fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } } diff --git a/vm/src/stdlib/marshal.rs b/vm/src/stdlib/marshal.rs index ad2c50fb10..1be96e9198 100644 --- a/vm/src/stdlib/marshal.rs +++ b/vm/src/stdlib/marshal.rs @@ -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()) } diff --git a/vm/src/stdlib/math.rs b/vm/src/stdlib/math.rs index 608b968a14..c922a4487c 100644 --- a/vm/src/stdlib/math.rs +++ b/vm/src/stdlib/math.rs @@ -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() } }; @@ -98,7 +98,7 @@ fn math_isclose(args: IsCloseArgs, vm: &VirtualMachine) -> PyResult { 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, _vm: &VirtualMachine) -> f64 { +fn math_log(x: IntoPyFloat, base: OptionalArg) -> 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()) } @@ -281,7 +281,7 @@ fn math_factorial(value: PyIntRef, vm: &VirtualMachine) -> PyResult { 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() { diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index b96ec766d5..fe4a729beb 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -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! @@ -519,11 +519,11 @@ 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 { + fn path(self) -> String { self.entry.path().to_str().unwrap().to_owned() } @@ -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, _vm: &VirtualMachine) -> PyRef { + fn iter(zelf: PyRef) -> PyRef { zelf } #[pymethod(name = "__enter__")] - fn enter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { + fn enter(zelf: PyRef) -> PyRef { zelf } #[pymethod(name = "__exit__")] - fn exit(zelf: PyRef, _args: PyFuncArgs, vm: &VirtualMachine) { - zelf.close(vm) + fn exit(zelf: PyRef, _args: PyFuncArgs) { + zelf.close() } } @@ -814,7 +814,6 @@ fn os_stat( _file: Either, _dir_fd: DirFd, _follow_symlinks: FollowSymlinks, - _vm: &VirtualMachine, ) -> PyResult { unimplemented!(); } @@ -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 { +fn os_system(command: PyStringRef) -> PyResult { 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) } @@ -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 } } diff --git a/vm/src/stdlib/pwd.rs b/vm/src/stdlib/pwd.rs index 0ad3942a49..5c2872e119 100644 --- a/vm/src/stdlib/pwd.rs +++ b/vm/src/stdlib/pwd.rs @@ -14,31 +14,31 @@ impl PyValue for Passwd { type PasswdRef = PyRef; impl PasswdRef { - fn pw_name(self, _vm: &VirtualMachine) -> String { + fn pw_name(self) -> String { self.name.clone() } - fn pw_passwd(self, _vm: &VirtualMachine) -> Option { + fn pw_passwd(self) -> Option { 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 { + fn pw_gecos(self) -> Option { 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() } } diff --git a/vm/src/stdlib/re.rs b/vm/src/stdlib/re.rs index 25203ba1c2..d819c86098 100644 --- a/vm/src/stdlib/re.rs +++ b/vm/src/stdlib/re.rs @@ -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()) } diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index 62a388ac81..e8ae729913 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -81,7 +81,7 @@ fn getsignal(signalnum: i32, vm: &VirtualMachine) -> PyResult { } #[cfg(unix)] -fn alarm(time: u32, _vm: &VirtualMachine) -> u32 { +fn alarm(time: u32) -> u32 { let prev_time = if time == 0 { sig_alarm::cancel() } else { diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index 220d01a8b4..b557dd8b83 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -231,12 +231,12 @@ impl PySocket { } #[pymethod] - fn close(&self, _vm: &VirtualMachine) { + fn close(&self) { self.sock.replace(invalid_sock()); } #[pymethod] - fn fileno(&self, _vm: &VirtualMachine) -> RawSocket { + fn fileno(&self) -> RawSocket { sock_fileno(&self.sock()) } @@ -361,15 +361,15 @@ impl PySocket { } #[pyproperty(name = "type")] - fn kind(&self, _vm: &VirtualMachine) -> i32 { + fn kind(&self) -> i32 { self.kind.get() } #[pyproperty] - fn family(&self, _vm: &VirtualMachine) -> i32 { + fn family(&self) -> i32 { self.family.get() } #[pyproperty] - fn proto(&self, _vm: &VirtualMachine) -> i32 { + fn proto(&self) -> i32 { self.proto.get() } } @@ -445,11 +445,11 @@ fn socket_inet_ntoa(packed_ip: PyBytesRef, vm: &VirtualMachine) -> PyResult { Ok(vm.new_str(Ipv4Addr::from(ip_num).to_string())) } -fn socket_hton(host: U, _vm: &VirtualMachine) -> U { +fn socket_hton(host: U) -> U { U::to_be(host) } -fn socket_ntoh(network: U, _vm: &VirtualMachine) -> U { +fn socket_ntoh(network: U) -> U { U::from_be(network) } diff --git a/vm/src/stdlib/subprocess.rs b/vm/src/stdlib/subprocess.rs index 35ae5115a7..403ba7ab44 100644 --- a/vm/src/stdlib/subprocess.rs +++ b/vm/src/stdlib/subprocess.rs @@ -134,11 +134,11 @@ impl PopenRef { .into_ref_with_type(vm, cls) } - fn poll(self, _vm: &VirtualMachine) -> Option { + fn poll(self) -> Option { self.process.borrow_mut().poll() } - fn return_code(self, _vm: &VirtualMachine) -> Option { + fn return_code(self) -> Option { self.process.borrow().exit_status() } @@ -209,11 +209,11 @@ impl PopenRef { }) } - fn pid(self, _vm: &VirtualMachine) -> Option { + fn pid(self) -> Option { self.process.borrow().pid() } - fn enter(self, _vm: &VirtualMachine) -> Self { + fn enter(self) -> Self { self } @@ -222,7 +222,6 @@ impl PopenRef { _exception_type: PyObjectRef, _exception_value: PyObjectRef, _traceback: PyObjectRef, - _vm: &VirtualMachine, ) { let mut process = self.process.borrow_mut(); process.stdout.take(); @@ -230,7 +229,7 @@ impl PopenRef { process.stderr.take(); } - fn args(self, _vm: &VirtualMachine) -> PyObjectRef { + fn args(self) -> PyObjectRef { self.args.clone() } } diff --git a/vm/src/stdlib/symtable.rs b/vm/src/stdlib/symtable.rs index d32afd44a2..f95c9fc916 100644 --- a/vm/src/stdlib/symtable.rs +++ b/vm/src/stdlib/symtable.rs @@ -87,17 +87,17 @@ impl PyValue for PySymbolTable { #[pyimpl] impl PySymbolTable { #[pymethod(name = "get_name")] - fn get_name(&self, _vm: &VirtualMachine) -> String { + fn get_name(&self) -> String { self.symtable.name.clone() } #[pymethod(name = "get_type")] - fn get_type(&self, _vm: &VirtualMachine) -> String { + fn get_type(&self) -> String { self.symtable.typ.to_string() } #[pymethod(name = "get_lineno")] - fn get_lineno(&self, _vm: &VirtualMachine) -> usize { + fn get_lineno(&self) -> usize { self.symtable.line_number } @@ -137,7 +137,7 @@ impl PySymbolTable { } #[pymethod(name = "has_children")] - fn has_children(&self, _vm: &VirtualMachine) -> bool { + fn has_children(&self) -> bool { !self.symtable.sub_tables.is_empty() } @@ -173,42 +173,42 @@ impl PyValue for PySymbol { #[pyimpl] impl PySymbol { #[pymethod(name = "get_name")] - fn get_name(&self, _vm: &VirtualMachine) -> String { + fn get_name(&self) -> String { self.symbol.name.clone() } #[pymethod(name = "is_global")] - fn is_global(&self, _vm: &VirtualMachine) -> bool { + fn is_global(&self) -> bool { self.symbol.is_global() } #[pymethod(name = "is_local")] - fn is_local(&self, _vm: &VirtualMachine) -> bool { + fn is_local(&self) -> bool { self.symbol.is_local() } #[pymethod(name = "is_referenced")] - fn is_referenced(&self, _vm: &VirtualMachine) -> bool { + fn is_referenced(&self) -> bool { self.symbol.is_referenced } #[pymethod(name = "is_assigned")] - fn is_assigned(&self, _vm: &VirtualMachine) -> bool { + fn is_assigned(&self) -> bool { self.symbol.is_assigned } #[pymethod(name = "is_parameter")] - fn is_parameter(&self, _vm: &VirtualMachine) -> bool { + fn is_parameter(&self) -> bool { self.symbol.is_parameter } #[pymethod(name = "is_free")] - fn is_free(&self, _vm: &VirtualMachine) -> bool { + fn is_free(&self) -> bool { self.symbol.is_free } #[pymethod(name = "is_namespace")] - fn is_namespace(&self, _vm: &VirtualMachine) -> bool { + fn is_namespace(&self) -> bool { // TODO false } diff --git a/vm/src/stdlib/thread.rs b/vm/src/stdlib/thread.rs index d32d65b9f7..44d345847a 100644 --- a/vm/src/stdlib/thread.rs +++ b/vm/src/stdlib/thread.rs @@ -16,7 +16,7 @@ fn rlock_acquire(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult { Ok(vm.get_none()) } -fn rlock_release(_zelf: PyObjectRef, _vm: &VirtualMachine) {} +fn rlock_release(_zelf: PyObjectRef) {} fn rlock_enter(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!(vm, args, required = [(instance, None)]); diff --git a/vm/src/stdlib/time_module.rs b/vm/src/stdlib/time_module.rs index c51354a163..a807535522 100644 --- a/vm/src/stdlib/time_module.rs +++ b/vm/src/stdlib/time_module.rs @@ -33,7 +33,7 @@ fn time_sleep(dur: Duration, vm: &VirtualMachine) -> PyResult<()> { } #[cfg(not(unix))] -fn time_sleep(dur: Duration, _vm: &VirtualMachine) { +fn time_sleep(dur: Duration) { std::thread::sleep(dur); } @@ -125,7 +125,7 @@ fn time_asctime(t: OptionalArg, vm: &VirtualMachine) -> PyResult { Ok(vm.ctx.new_str(formatted_time)) } -fn time_ctime(secs: OptionalArg>, _vm: &VirtualMachine) -> String { +fn time_ctime(secs: OptionalArg>) -> String { let instant = optional_or_localtime(secs); instant.format(&CFMT).to_string() } diff --git a/vm/src/stdlib/unicodedata.rs b/vm/src/stdlib/unicodedata.rs index 9507d337fb..713de4fe18 100644 --- a/vm/src/stdlib/unicodedata.rs +++ b/vm/src/stdlib/unicodedata.rs @@ -165,7 +165,7 @@ impl PyUCD { } #[pyproperty] - fn unidata_version(&self, _vm: &VirtualMachine) -> String { + fn unidata_version(&self) -> String { self.unic_version.to_string() } } diff --git a/vm/src/stdlib/weakref.rs b/vm/src/stdlib/weakref.rs index 00045e7de3..0e22432330 100644 --- a/vm/src/stdlib/weakref.rs +++ b/vm/src/stdlib/weakref.rs @@ -9,7 +9,7 @@ use crate::pyobject::PyObjectRef; use crate::vm::VirtualMachine; use std::rc::Rc; -fn weakref_getweakrefcount(obj: PyObjectRef, _vm: &VirtualMachine) -> usize { +fn weakref_getweakrefcount(obj: PyObjectRef) -> usize { Rc::weak_count(&obj) } @@ -18,7 +18,7 @@ fn weakref_getweakrefs(_obj: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef { vm.ctx.new_list(vec![]) } -fn weakref_remove_dead_weakref(_obj: PyObjectRef, _key: PyObjectRef, _vm: &VirtualMachine) { +fn weakref_remove_dead_weakref(_obj: PyObjectRef, _key: PyObjectRef) { // TODO } diff --git a/vm/src/sysmodule.rs b/vm/src/sysmodule.rs index fdb04de47e..431952c8bc 100644 --- a/vm/src/sysmodule.rs +++ b/vm/src/sysmodule.rs @@ -97,11 +97,11 @@ impl SysFlags { } } -fn sys_getrefcount(obj: PyObjectRef, _vm: &VirtualMachine) -> usize { +fn sys_getrefcount(obj: PyObjectRef) -> usize { Rc::strong_count(&obj) } -fn sys_getsizeof(obj: PyObjectRef, _vm: &VirtualMachine) -> usize { +fn sys_getsizeof(obj: PyObjectRef) -> usize { // TODO: implement default optional argument. mem::size_of_val(&obj) } @@ -170,7 +170,7 @@ fn sys_setrecursionlimit(recursion_limit: usize, vm: &VirtualMachine) -> PyResul } // TODO implement string interning, this will be key for performance -fn sys_intern(value: PyStringRef, _vm: &VirtualMachine) -> PyStringRef { +fn sys_intern(value: PyStringRef) -> PyStringRef { value } diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 53ef276cf7..6d3493bf31 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -1220,7 +1220,7 @@ impl VirtualMachine { pub fn _hash(&self, obj: &PyObjectRef) -> PyResult { let hash_obj = self.call_method(obj, "__hash__", vec![])?; if let Some(hash_value) = hash_obj.payload_if_subclass::(self) { - Ok(hash_value.hash(self)) + Ok(hash_value.hash()) } else { Err(self.new_type_error("__hash__ method should return an integer".to_owned())) } diff --git a/wasm/lib/src/js_module.rs b/wasm/lib/src/js_module.rs index bd7e5250a9..72497c43aa 100644 --- a/wasm/lib/src/js_module.rs +++ b/wasm/lib/src/js_module.rs @@ -72,22 +72,22 @@ impl PyJsValue { } #[pymethod] - fn null(&self, _vm: &VirtualMachine) -> PyJsValue { + fn null(&self) -> PyJsValue { PyJsValue::new(JsValue::NULL) } #[pymethod] - fn undefined(&self, _vm: &VirtualMachine) -> PyJsValue { + fn undefined(&self) -> PyJsValue { PyJsValue::new(JsValue::UNDEFINED) } #[pymethod] - fn new_from_str(&self, s: PyStringRef, _vm: &VirtualMachine) -> PyJsValue { + fn new_from_str(&self, s: PyStringRef) -> PyJsValue { PyJsValue::new(s.as_str()) } #[pymethod] - fn new_from_float(&self, n: PyFloatRef, _vm: &VirtualMachine) -> PyJsValue { + fn new_from_float(&self, n: PyFloatRef) -> PyJsValue { PyJsValue::new(n.to_f64()) } @@ -185,29 +185,29 @@ impl PyJsValue { } #[pymethod] - fn as_str(&self, _vm: &VirtualMachine) -> Option { + fn as_str(&self) -> Option { self.value.as_string() } #[pymethod] - fn as_float(&self, _vm: &VirtualMachine) -> Option { + fn as_float(&self) -> Option { self.value.as_f64() } #[pymethod] - fn as_bool(&self, _vm: &VirtualMachine) -> Option { + fn as_bool(&self) -> Option { self.value.as_bool() } #[pymethod(name = "typeof")] - fn type_of(&self, _vm: &VirtualMachine) -> String { + fn type_of(&self) -> String { type_of(&self.value) } #[pymethod] /// Checks that `typeof self == "object" && self !== null`. Use instead /// of `value.typeof() == "object"` - fn is_object(&self, _vm: &VirtualMachine) -> bool { + fn is_object(&self) -> bool { self.value.is_object() } @@ -217,7 +217,7 @@ impl PyJsValue { } #[pymethod(name = "__repr__")] - fn repr(&self, _vm: &VirtualMachine) -> String { + fn repr(&self) -> String { format!("{:?}", self.value) } } From 92cb58b163c593e0d5d66d9b6aae1642625ba2c5 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 6 Feb 2020 18:54:37 +0900 Subject: [PATCH 26/26] Remove `_vm` parameter - remove unused functions --- vm/src/exceptions.rs | 38 +++++++------------------------------- vm/src/stdlib/socket.rs | 16 ++++------------ 2 files changed, 11 insertions(+), 43 deletions(-) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 83023d9d2e..3c8844c9f2 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -67,8 +67,8 @@ impl PyBaseException { Ok(()) } - #[pyproperty(name = "args")] - fn get_args(&self) -> PyTupleRef { + #[pyproperty] + pub fn args(&self) -> PyTupleRef { self.args.borrow().clone() } @@ -80,7 +80,7 @@ impl PyBaseException { } #[pyproperty(name = "__traceback__")] - fn get_traceback(&self) -> Option { + pub fn traceback(&self) -> Option { self.traceback.borrow().clone() } @@ -90,25 +90,23 @@ impl PyBaseException { } #[pyproperty(name = "__cause__")] - fn get_cause(&self) -> Option { + pub fn cause(&self) -> Option { self.cause.borrow().clone() } #[pyproperty(name = "__cause__", setter)] - fn setter_cause(&self, cause: Option) -> PyResult<()> { + pub fn set_cause(&self, cause: Option) { self.cause.replace(cause); - Ok(()) } #[pyproperty(name = "__context__")] - fn get_context(&self) -> Option { + pub fn context(&self) -> Option { self.context.borrow().clone() } #[pyproperty(name = "__context__", setter)] - fn setter_context(&self, context: Option) -> PyResult<()> { + pub fn set_context(&self, context: Option) { self.context.replace(context); - Ok(()) } #[pyproperty(name = "__suppress_context__")] @@ -146,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 { - self.traceback.borrow().clone() - } - - pub fn cause(&self) -> Option { - self.cause.borrow().clone() - } - pub fn set_cause(&self, cause: Option) { - self.cause.replace(cause); - } - - pub fn context(&self) -> Option { - self.context.borrow().clone() - } - pub fn set_context(&self, context: Option) { - self.context.replace(context); - } } /// Print exception chain diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index b557dd8b83..4548cb1194 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -445,14 +445,6 @@ fn socket_inet_ntoa(packed_ip: PyBytesRef, vm: &VirtualMachine) -> PyResult { Ok(vm.new_str(Ipv4Addr::from(ip_num).to_string())) } -fn socket_hton(host: U) -> U { - U::to_be(host) -} - -fn socket_ntoh(network: U) -> U { - U::from_be(network) -} - #[derive(FromArgs)] struct GAIOptions { #[pyarg(positional_only)] @@ -618,10 +610,10 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "inet_aton" => ctx.new_function(socket_inet_aton), "inet_ntoa" => ctx.new_function(socket_inet_ntoa), "gethostname" => ctx.new_function(socket_gethostname), - "htonl" => ctx.new_function(socket_hton::), - "htons" => ctx.new_function(socket_hton::), - "ntohl" => ctx.new_function(socket_ntoh::), - "ntohs" => ctx.new_function(socket_ntoh::), + "htonl" => ctx.new_function(u32::to_be), + "htons" => ctx.new_function(u16::to_be), + "ntohl" => ctx.new_function(u32::from_be), + "ntohs" => ctx.new_function(u16::from_be), "getdefaulttimeout" => ctx.new_function(|vm: &VirtualMachine| vm.get_none()), "has_ipv6" => ctx.new_bool(false), // constants